Pythonのcompile()関数は、コードを事前にコンパイルしてコードオブジェクトを生成する関数です。この関数を使うことで、同じコードを繰り返し実行する際のパフォーマンスを向上させることができます。

compile()関数の基本的な使い方

compile()関数の基本的な構文は以下の通りです:

compile(source, filename, mode)
  • source: コンパイルするコードを文字列として指定
  • filename: コードのファイル名(通常は''を使用)
  • mode: コンパイルモード('exec'、'eval'、'single'のいずれか)

コンパイルモードの違い

evalモード

単一の式を評価する場合に使用します。

# 式のコンパイル
code = compile('2 + 3', '<string>', 'eval')
result = eval(code)
print(result)  # 出力: 5

execモード

複数行のPythonコードを実行する場合に使用します。

# 複数行のコードをコンパイル
code = compile('''
x = 1
y = 2
print(x + y)
''', '<string>', 'exec')
exec(code)  # 出力: 3

singleモード

対話型シェルのような1つの文を実行する場合に使用します。

code = compile('print("Hello")', '<string>', 'single')
exec(code)  # 出力: Hello

compile()関数の実践的な使用例

数式の計算

# 数式を変数として扱う
formula = 'x**2 + y**2'
code = compile(formula, '<string>', 'eval')

# 異なる値で同じ式を評価
x, y = 3, 4
result1 = eval(code)
print(result1)  # 出力: 25

x, y = 1, 2
result2 = eval(code)
print(result2)  # 出力: 5

動的なコード実行

# ユーザー入力に基づいてコードを実行
user_code = '''
def greet(name):
    return f"Hello, {name}!"
'''

# コードをコンパイル
compiled_code = compile(user_code, '<string>', 'exec')

# コードを実行
exec(compiled_code)

# 関数を使用
result = eval('greet("Python")')
print(result)  # 出力: Hello, Python!

エラー処理とセキュリティ

compile()関数を使用する際は、以下の点に注意が必要です:

try:
    # 不正なコードのコンパイル
    code = compile('print(x', '<string>', 'exec')
except SyntaxError:
    print("構文エラーが発生しました")

# セキュリティ対策
def safe_compile(source):
    # 危険な関数や操作を含むコードをブロック
    if 'os.' in source or 'system' in source:
        raise ValueError("不正な操作が含まれています")
    return compile(source, '<string>', 'exec')

パフォーマンスの最適化

compile()関数は、同じコードを複数回実行する場合に特に効果を発揮します:

import time

# コンパイル済みコードと未コンパイルコードの比較
code = 'sum([i**2 for i in range(1000)])'

# コンパイル済み
start = time.time()
compiled = compile(code, '<string>', 'eval')
for _ in range(1000):
    eval(compiled)
print(f"コンパイル済み: {time.time() - start}秒")

# 未コンパイル
start = time.time()
for _ in range(1000):
    eval(code)
print(f"未コンパイル: {time.time() - start}秒")

compile()関数は、動的なコード実行やパフォーマンスの最適化が必要な場合に非常に有用なツールです。ただし、セキュリティリスクを考慮し、信頼できるソースからのコードのみを実行するようにしましょう。