1. はじめに
Pythonにはcompile()関数という、文字列をPythonコードとして「実行可能な形式」に変換する強力な関数があります。普段のプログラミングではあまり使わないかもしれませんが、実はeval()やexec()と組み合わせて動的なコード実行が必要な場面で活躍します。
本記事では、Pythonのcompile()関数の基本的な使い方から応用例、注意点までを初心者にもわかりやすく解説します。最終的には、「こんな場面で使える!」という実務寄りのヒントもご紹介しますので、ぜひ最後までご覧ください。
2. Pythonのcompile()関数とは?
2-1. compile()関数の概要
compile()関数は、Pythonの文字列(str)やAST(抽象構文木)を、Pythonが実行可能な「コードオブジェクト(code object)」に変換するための関数です。
構文は以下の通りです。
compile(source, filename, mode)
- source:実行したいPythonコード(文字列)
- filename:通常は”<string>”と指定
- mode:‘exec’、’eval’、’single’のいずれか
2-2. 基本的な使い方の例
以下は、文字列から簡単な計算式を実行する例です。
# 文字列をPythonコードとしてコンパイルして評価する
code = compile("3 + 4", "", "eval")
result = eval(code)
print(result)
実行結果:
7
このように、compile()を使うと、文字列をそのまま計算式として処理できます。特に、外部から入力されたコードを動的に扱いたい場合に便利です。
3. よくある使い方・応用例
3-1. exec()と組み合わせた複数行コードの実行
次は、複数行のPythonコードを文字列として実行する例です。
code_str = """
for i in range(3):
print(f'ループ: {i}')
"""
compiled = compile(code_str, "", "exec")
exec(compiled)
実行結果:
ループ: 0
ループ: 1
ループ: 2
このように、mode=’exec’を指定することで、関数定義やforループなど複数行のコードも安全に扱えます。
3-2. eval()と組み合わせた動的な式評価
変数を含んだ計算式を文字列から評価したい場合もcompile()は役立ちます。
x = 10
expr = "x * 5 + 2"
compiled_expr = compile(expr, "", "eval")
result = eval(compiled_expr)
print(result)
実行結果:
52
この方法を使えば、ユーザーが入力した式を検証・制御しながら安全に処理することも可能になります。
3-3. セキュリティやサンドボックス環境での活用
Webアプリや教育系ツールでは、ユーザーが入力したPythonコードを動的に実行したい場面があります。その際、事前にcompile()を通すことで、構文チェックや意図しない命令の抑制が可能になります。
4. 注意点・エラー対策
4-1. SyntaxErrorに注意
compile()は構文が正しくないとSyntaxErrorを発生させます。例を見てみましょう。
# 間違った構文(コロンがない)
code = compile("for i in range(3) print(i)", "", "exec")
実行結果:
SyntaxError: invalid syntax
コードを事前にチェックする、try-exceptで囲むなどの対策が必要です。
4-2. セキュリティ面のリスク
ユーザーからの入力をそのままeval()やexec()で実行するのは非常に危険です。悪意あるコード(例:os.system("rm -rf /")
など)を防ぐため、実行環境を制限する工夫(globalsやlocalsの制御)が必要です。
4-3. compile()で使えるmodeの違い
- ‘eval’:単一の式だけを対象。例:
"2 + 3"
- ‘exec’:複数行のコード、文全体を対象。例:for文など
- ‘single’:対話型モードに近く、1行ごとに評価される(基本的には非推奨)
5. まとめ
この記事では、Pythonのcompile()関数について以下の内容を学びました。
- 文字列をPythonコードとして実行可能にする方法
- eval()やexec()との組み合わせ
- 構文チェックやセキュリティ制御への応用
compile()関数はややニッチではありますが、動的コード実行・教育系ツール・セキュリティ対策といった実務において強力な武器となります。
特に、eval()やexec()を扱う前に一度compile()を挟むことで、安全性と柔軟性の両方を確保できます。ぜひ、Pythonをより深く理解するための一歩として、活用してみてください。