Python evalの使い方を簡単に解説
Python eval(): 式を動的に評価する
Pythonのeval()
関数は、文字列ベースやコンパイルコードベースの入力から任意のPython式を評価することができます。この関数は、文字列やコンパイルされたコードオブジェクトとして渡される任意の入力からPython式を動的に評価する場合に便利です。
ただし、eval()
関数はセキュリティ上の重要な問題があるため、使用する前に注意が必要です。このチュートリアルでは、eval()
の働き方や安全に効果的に使用する方法について学びます。
Understanding Python’s eval()
Pythonの組み込み関数であるeval()
を使用すると、文字列ベースやコンパイルコードベースの入力から式を動的に評価できます。eval()
に文字列を渡すと、関数はそれを解析し、バイトコードにコンパイルし、Pythonの式として評価します。一方、コンパイルされたコードオブジェクトを使ってeval()
を呼び出すと、関数は評価ステップのみを実行します。
Pythonのeval()
のシグネチャは以下の通りです。
関数は、第1引数であるexpression
に評価する式を保持しています。eval()
にはさらに2つのオプション引数があります。
globals
locals
次の3つのセクションでは、これらの引数が何であるか、そしてeval()
がこれらをどのように使ってPythonの式を評価するのかについて学びます。
注意: eval()
と同様に、exec()
も動的にPythonコードを実行することができます。
The First Argument: expression
eval()
の第1引数であるexpression
は、評価する式を保持しています。この式は文字列として渡されます。
例えば、以下のような式を評価する場合、expression
には文字列"2 + 3"
を渡します。
eval()
はexpression
を評価し、その結果を返します。
The Second Argument: globals
eval()
の第2引数であるglobals
は、グローバル名前空間を指定するための辞書オブジェクトです。この辞書には、expression
内で使用されるグローバル変数の値や関数を定義することができます。
例えば、以下のような式を評価する場合、globals
には辞書{"x": 2, "y": 3}
を渡します。これにより、expression
内で変数x
と変数y
が使えるようになります。
eval()
はexpression
内でx
とy
の値を取得し、その結果を返します。
The Third Argument: locals
eval()
の第3引数であるlocals
は、ローカル名前空間を指定するための辞書オブジェクトです。この辞書には、expression
内で使用されるローカル変数の値を定義することができます。
例えば、以下のような式を評価する場合、locals
に辞書{"x": 2}
を渡します。これにより、expression
内で変数x
が使えるようになります。
eval()
はexpression
内でx
の値を取得し、locals
内のy
の値を無視してその結果を返します。
Evaluating Expressions With Python’s eval()
eval()
を使ってPythonの式を評価することができます。ここでは、真偽値式、数式、汎用式の評価方法について見ていきましょう。
Boolean Expressions
eval()
を使って真偽値式を評価することができます。真偽値式はTrue
またはFalse
を返す式です。
例えば、以下のような真偽値式を評価する場合、expression
には文字列"2 > 3"
を渡します。
eval()
は真偽値式を評価し、その結果を返します。
Math Expressions
eval()
を使って数式を評価することもできます。数式は数値を返す式です。
例えば、以下のような数式を評価する場合、expression
には文字列"2 + 3"
を渡します。
eval()
は数式を評価し、その結果を返します。
General-Purpose Expressions
eval()
は汎用のPython式も評価することができます。これにより、さまざまな種類の式を動的に評価することができます。
例えば、以下のような式を評価する場合、expression
には任意のPython式を渡します。
eval()
は式を評価し、その結果を返します。この場合、x
はグローバル名前空間にないため、globals
に指定された辞書が使われます。
Minimizing the Security Issues of eval()
eval()
のセキュリティ上の問題を最小限に抑えるための方法を学びましょう。
Restricting globals and locals
eval()
を安全に使用するためには、globals
とlocals
を制限する必要があります。これにより、エンドユーザーが実行するコードが予期しない変数や関数にアクセスすることを防ぐことができます。
例えば、以下のようにglobals
とlocals
を空の辞書にすることで、式を評価する際に特定の変数や関数にアクセスできなくなります。
eval()
は変数x
にアクセスできないため、NameError
が発生します。
Restricting the Use of Built-In Names
Pythonの組み込み関数や組み込みクラスの名前も制限することができます。これにより、意図しない関数やクラスが実行されることを防ぐことができます。
例えば、以下のようにglobals
とlocals
に__builtins__
を空の辞書にすることで、組み込み関数や組み込みクラスの使用を制限することができます。
eval()
は組み込み関数sum()
にアクセスできないため、NameError
が発生します。
Restricting Names in the Input
eval()
に渡される入力内の変数や関数名も制限することができます。これにより、エンドユーザーが特定の変数や関数名を使用することを防ぐことができます。
例えば、以下のようにlocals
に特定の変数を定義することで、評価する式内で他の変数を使用できなくすることができます。
eval()
は式内で変数y
にアクセスできないため、NameError
が発生します。
Restricting the Input to Only Literals
最も安全な方法は、eval()
に渡す入力をリテラルのみに制限することです。リテラルは、文字列や数値などの固定値です。
例えば、以下のように式が数式だけで構成されている場合、eval()
は安全に評価されます。
この例では、eval()
に渡される入力が数式のみで構成されていることが確認され、安全に評価されます。
Using Python’s eval() With input()
eval()
をinput()
関数と組み合わせて使用すると、ユーザーが入力した式を評価することができます。
例えば、以下のようにinput()
関数を使ってユーザーに数式を入力させ、eval()
を使って評価します。
ユーザーは数式を入力し、eval()
はその数式を評価して結果を表示します。
Building a Math Expressions Evaluator
ここまでの内容を元に、数式を評価するアプリケーションを作成してみましょう。
以下は、eval()
を使って数式を評価するための関数evaluate_expression()
を定義する例です。
この関数では、eval()
を使って式を評価しています。
Conclusion
このチュートリアルでは、Pythonのeval()
関数について学びました。eval()
を使うことで、文字列ベースやコンパイルコードベースの入力からPythonの式を動的に評価することができます。
ただし、eval()
を使用する際にはセキュリティ上の問題に注意する必要があります。eval()
を安全に使用するためには、globalsやlocalsを制限し、組み込み関数や組み込みクラスの使用を制限し、入力内の変数や関数名を制限する必要があります。
また、eval()
を使って数式を評価するアプリケーションを作成する方法も学びました。
以上が、Pythonのeval()
についての解説です。安全に使用し、Pythonプログラムにおける効果的な活用に役立ててください。