Pythonでコード文字列を実行する際によく使用される`exec()`関数について解説します。`exec()`関数は文字列として記述されたPythonコードを実行できる強力な機能を持っていますが、使い方を誤るとセキュリティ上のリスクがあるため、適切な理解が必要です。

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

`exec()`関数の最もシンプルな使用方法は以下の通りです:

code = "print('Hello, World!')"
exec(code)  # 出力: Hello, World!

複数行のコード実行

複数行のコードも実行可能です:

code = """
x = 10
y = 20
print(x + y)
"""
exec(code)  # 出力: 30

グローバル変数とローカル変数の扱い

`exec()`は第2引数と第3引数で名前空間を指定できます:

# グローバル名前空間を指定
globals_dict = {}
exec("x = 100", globals_dict)
print(globals_dict['x'])  # 出力: 100

# ローカル名前空間も指定
locals_dict = {}
exec("y = 200", globals_dict, locals_dict)
print(locals_dict['y'])  # 出力: 200

セキュリティ上の注意点

`exec()`は任意のコードを実行できるため、信頼できない入力には使用しないでください:

# 危険な例 - 絶対に行わないでください
user_input = input("コードを入力: ")
exec(user_input)  # セキュリティリスクあり

安全な代替手段

文字列からの値の評価が必要な場合は、より安全な`ast.literal_eval()`を使用することを推奨します:

from ast import literal_eval

# 安全な文字列評価
result = literal_eval('{"name": "Python", "version": 3.9}')
print(result)  # 出力: {'name': 'Python', 'version': 3.9}

エラー処理

`exec()`実行時のエラーは適切に処理する必要があります:

try:
    exec("print(undefined_variable)")
except NameError as e:
    print(f"エラーが発生しました: {e}")

実践的な使用例

設定ファイルの動的読み込みなど、実用的な例を示します:

# 設定ファイルの例
config_string = """
DEBUG = True
MAX_CONNECTIONS = 100
DATABASE = {
    'host': 'localhost',
    'port': 5432
}
"""

config = {}
exec(config_string, {}, config)
print(config['DEBUG'])  # 出力: True
print(config['DATABASE']['host'])  # 出力: localhost

まとめ

`exec()`関数は強力な機能を提供しますが、以下の点に注意して使用してください:

  • 信頼できるソースからのコードのみを実行
  • 可能な限り代替手段を検討
  • 適切なエラー処理の実装
  • 名前空間の分離による安全性の確保

これらの注意点を守ることで、`exec()`を安全かつ効果的に活用できます。