コンテンツにスキップ

Python evalの使い方を簡単に解説

[

Python eval(): 式を動的に評価する

Pythonのeval()関数は、文字列ベースやコンパイルコードベースの入力から任意のPython式を評価することができます。この関数は、文字列やコンパイルされたコードオブジェクトとして渡される任意の入力からPython式を動的に評価する場合に便利です。

ただし、eval()関数はセキュリティ上の重要な問題があるため、使用する前に注意が必要です。このチュートリアルでは、eval()の働き方や安全に効果的に使用する方法について学びます。

Understanding Python’s eval()

Pythonの組み込み関数であるeval()を使用すると、文字列ベースやコンパイルコードベースの入力から式を動的に評価できます。eval()に文字列を渡すと、関数はそれを解析し、バイトコードにコンパイルし、Pythonの式として評価します。一方、コンパイルされたコードオブジェクトを使ってeval()を呼び出すと、関数は評価ステップのみを実行します。

Pythonのeval()のシグネチャは以下の通りです。

eval(expression[, globals[, locals]])

関数は、第1引数であるexpressionに評価する式を保持しています。eval()にはさらに2つのオプション引数があります。

  1. globals
  2. locals

次の3つのセクションでは、これらの引数が何であるか、そしてeval()がこれらをどのように使ってPythonの式を評価するのかについて学びます。

注意: eval()と同様に、exec()も動的にPythonコードを実行することができます。

The First Argument: expression

eval()の第1引数であるexpressionは、評価する式を保持しています。この式は文字列として渡されます。

例えば、以下のような式を評価する場合、expressionには文字列"2 + 3"を渡します。

result = eval("2 + 3")
print(result) # Output: 5

eval()expressionを評価し、その結果を返します。

The Second Argument: globals

eval()の第2引数であるglobalsは、グローバル名前空間を指定するための辞書オブジェクトです。この辞書には、expression内で使用されるグローバル変数の値や関数を定義することができます。

例えば、以下のような式を評価する場合、globalsには辞書{"x": 2, "y": 3}を渡します。これにより、expression内で変数xと変数yが使えるようになります。

result = eval("x + y", {"x": 2, "y": 3})
print(result) # Output: 5

eval()expression内でxyの値を取得し、その結果を返します。

The Third Argument: locals

eval()の第3引数であるlocalsは、ローカル名前空間を指定するための辞書オブジェクトです。この辞書には、expression内で使用されるローカル変数の値を定義することができます。

例えば、以下のような式を評価する場合、localsに辞書{"x": 2}を渡します。これにより、expression内で変数xが使えるようになります。

result = eval("x + y", {"x": 2}, {"y": 3})
print(result) # Output: 5

eval()expression内でxの値を取得し、locals内のyの値を無視してその結果を返します。

Evaluating Expressions With Python’s eval()

eval()を使ってPythonの式を評価することができます。ここでは、真偽値式、数式、汎用式の評価方法について見ていきましょう。

Boolean Expressions

eval()を使って真偽値式を評価することができます。真偽値式はTrueまたはFalseを返す式です。

例えば、以下のような真偽値式を評価する場合、expressionには文字列"2 > 3"を渡します。

result = eval("2 > 3")
print(result) # Output: False

eval()は真偽値式を評価し、その結果を返します。

Math Expressions

eval()を使って数式を評価することもできます。数式は数値を返す式です。

例えば、以下のような数式を評価する場合、expressionには文字列"2 + 3"を渡します。

result = eval("2 + 3")
print(result) # Output: 5

eval()は数式を評価し、その結果を返します。

General-Purpose Expressions

eval()は汎用のPython式も評価することができます。これにより、さまざまな種類の式を動的に評価することができます。

例えば、以下のような式を評価する場合、expressionには任意のPython式を渡します。

result = eval("2 + x", {"x": 3})
print(result) # Output: 5

eval()は式を評価し、その結果を返します。この場合、xはグローバル名前空間にないため、globalsに指定された辞書が使われます。

Minimizing the Security Issues of eval()

eval()のセキュリティ上の問題を最小限に抑えるための方法を学びましょう。

Restricting globals and locals

eval()を安全に使用するためには、globalslocalsを制限する必要があります。これにより、エンドユーザーが実行するコードが予期しない変数や関数にアクセスすることを防ぐことができます。

例えば、以下のようにglobalslocalsを空の辞書にすることで、式を評価する際に特定の変数や関数にアクセスできなくなります。

result = eval("2 + x", {}, {})
print(result) # Raises a NameError

eval()は変数xにアクセスできないため、NameErrorが発生します。

Restricting the Use of Built-In Names

Pythonの組み込み関数や組み込みクラスの名前も制限することができます。これにより、意図しない関数やクラスが実行されることを防ぐことができます。

例えば、以下のようにglobalslocals__builtins__を空の辞書にすることで、組み込み関数や組み込みクラスの使用を制限することができます。

result = eval("sum([1, 2, 3])", {"__builtins__": {}}, {})
print(result) # Raises a NameError

eval()は組み込み関数sum()にアクセスできないため、NameErrorが発生します。

Restricting Names in the Input

eval()に渡される入力内の変数や関数名も制限することができます。これにより、エンドユーザーが特定の変数や関数名を使用することを防ぐことができます。

例えば、以下のようにlocalsに特定の変数を定義することで、評価する式内で他の変数を使用できなくすることができます。

result = eval("x + y", {"x": 2}, {"y": 3})
print(result) # Raises a NameError

eval()は式内で変数yにアクセスできないため、NameErrorが発生します。

Restricting the Input to Only Literals

最も安全な方法は、eval()に渡す入力をリテラルのみに制限することです。リテラルは、文字列や数値などの固定値です。

例えば、以下のように式が数式だけで構成されている場合、eval()は安全に評価されます。

expression = input("Enter a math expression: ")
if all(c.isdigit() or c in "+-*/" for c in expression):
result = eval(expression)
print(result)
# Example input: "2 + 3"
# Output: 5

この例では、eval()に渡される入力が数式のみで構成されていることが確認され、安全に評価されます。

Using Python’s eval() With input()

eval()input()関数と組み合わせて使用すると、ユーザーが入力した式を評価することができます。

例えば、以下のようにinput()関数を使ってユーザーに数式を入力させ、eval()を使って評価します。

expression = input("Enter a math expression: ")
result = eval(expression)
print(result)

ユーザーは数式を入力し、eval()はその数式を評価して結果を表示します。

Building a Math Expressions Evaluator

ここまでの内容を元に、数式を評価するアプリケーションを作成してみましょう。

以下は、eval()を使って数式を評価するための関数evaluate_expression()を定義する例です。

def evaluate_expression(expression):
return eval(expression)
# Example usage:
result = evaluate_expression("2 + 3")
print(result) # Output: 5

この関数では、eval()を使って式を評価しています。

Conclusion

このチュートリアルでは、Pythonのeval()関数について学びました。eval()を使うことで、文字列ベースやコンパイルコードベースの入力からPythonの式を動的に評価することができます。

ただし、eval()を使用する際にはセキュリティ上の問題に注意する必要があります。eval()を安全に使用するためには、globalsやlocalsを制限し、組み込み関数や組み込みクラスの使用を制限し、入力内の変数や関数名を制限する必要があります。

また、eval()を使って数式を評価するアプリケーションを作成する方法も学びました。

以上が、Pythonのeval()についての解説です。安全に使用し、Pythonプログラムにおける効果的な活用に役立ててください。