Python で関数を動的に生成する(exec, eval)

exec や eval を使うと、文字列からコードを実行したり、関数を動的に生成したりできます。強力な機能ですが、セキュリティには注意が必要です。

eval:式を評価する

eval は文字列を式として評価し、結果を返します。

result = eval("2 + 3 * 4")
print(result)  # 14

x = 10
result = eval("x * 2")
print(result)  # 20

exec:文を実行する

exec は文字列をコードとして実行します。値を返しません。

code = """
def greet(name):
    return f"Hello, {name}!"
"""

exec(code)
print(greet("Alice"))  # Hello, Alice!

関数を動的に生成する

実行時に関数を作成できます。

def make_power_function(n):
    code = f"""
def power(x):
    return x ** {n}
"""
    namespace = {}
    exec(code, namespace)
    return namespace["power"]

square = make_power_function(2)
cube = make_power_function(3)
print(square(5))  # 25
print(cube(5))    # 125

名前空間の制御

exec と eval は名前空間を指定できます。

namespace = {"x": 10, "y": 20}
result = eval("x + y", namespace)
print(result)  # 30

セキュリティ上の注意

ユーザー入力を直接 eval / exec に渡してはいけない
信頼できないコードの実行は危険
可能なら ast.literal_eval など安全な代替手段を使う

動的なコード生成はメタプログラミングやコード生成ツールで有用ですが、悪意あるコードが実行される可能性を常に意識してください。