【Python】Eval関数の書き方を実コード付きで解説

※本サイトにはプロモーション・広告が含まれています。

(最終更新日:2023年7月)

✔当記事は以下のような方に向けてかかれています

「PythonのEval関数とは何だろう?」
「PythonのEval関数の使い方を学びたい」
「Eval関数を使った実践例が知りたい」

✔当記事でご紹介する内容

  • Python Eval関数の基本
  • Python Evalの適切な使い方と応用方法
  • Python Eva関数の実例

当記事では、Eval関数の基本から応用までを、実例を交えてわかりやすくご紹介します。

ぜひ最後までお読みください。

筆者プロフィール

筆者プロフィールアイコン

【現職】プロジェクトマネージャー/SE(元外資系金融機関営業)

【副業】ブログ(月間15万PV)/YouTube/Web・アプリ制作

コミュニケーション × ビジネススキル × 文章力 × プログラミングスキルを活かし、30後半からのIT系職へシフト。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

eval()関数の基本

こちらでは、eval()関数の基本的な使い方について詳しく見ていきます。

  • Pythonにおけるeval()関数とは?
  • 文字列から数値やデータ型への変換
  • 数式文字列の評価
  • eval()関数の引数の使い方

Pythonにおけるeval()関数とは?

eval()はPythonにおいて、文字列として表されたPython式を評価して、その結果を返す関数です。

動的に式を生成して実行することが可能となります。

例えば、ユーザーからの入力を用いて計算を行ったり、文字列からPythonオブジェクトを生成するなど、多岐にわたる用途があります。

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

文字列から数値やデータ型への変換

eval()関数を使って、文字列をPythonの数値やデータ型に変換できます。

例えば、整数を表す文字列を実際の整数に変換する例を見てみましょう。

s = "123"
result = eval(s)
print(type(result), result)  # <class 'int'> 123

数式文字列の評価

eval()関数は、数式を含む文字列を評価して、計算結果を得るのにも使えます。

これは動的に計算式を生成する際などに非常に便利です。

expression = "5 * 6 - 2"
result = eval(expression)
print(result)  # 28

eval()関数の引数の使い方

eval()関数は通常、ひとつの引数(評価する文字列)を取ります。

ただし追加で、グローバルおよびローカルの名前空間を指定する引数を渡すことも可能。

eval()関数のスコープにある変数へのアクセスを制御できるのです。

x = 10
expression = "x + 5"
result = eval(expression, {"x": 2})
print(result)  # 7, x was overridden to 2 in the scope of eval()

compile関数との違い

こちらでは、eval()関数と似た機能を持つcompile()関数との違いについて解説します。

  • compile関数の概要
  • compile関数とeval()関数の使い分け

compile関数の概要

compile()関数は、Pythonのコードを文字列として受け取り、後でexec()またはeval()関数で実行できるコードオブジェクトを生成します。

同じコードを何度も実行する場合、効率を向上させられるのです。

code = compile('x + 2', '<string>', 'eval')
x = 5
result = eval(code)
print(result)  # 7

compile関数とeval()関数の使い分け

compile()関数を使用する場面は以下のようなときです。

  • 大規模なコードを繰り返し実行する際に効率を向上させたいとき
  • 動的に生成されたコードを後で実行したいとき

eval()関数は、単純な式の評価や小規模なコードの実行に適しています。

安全性と代替手段

こちらでは、eval()関数のセキュリティ面でのリスクと、それに対する安全な代替手段について解説します。

  • eval()関数のセキュリティリスク
  • Pythonで入力値をエスケープする方法
  • literal_eval()関数を使った安全な評価
  • eval()関数を使用する際の注意点

eval()関数のセキュリティリスク

eval()関数は任意のコードを実行するため、悪意あるコードを実行されるリスクがあります。

例えば、ユーザーからの入力をそのままeval()関数で評価すると、システムに悪影響を及ぼすコードを実行される可能性があります。

ユーザーからの入力を直接eval()関数に渡す場合は、慎重に入力のバリデーションやエスケープ処理をおこないましょう。

セキュリティ上のリスクを回避するためには、代替手段を検討することも重要です。

Pythonで入力値をエスケープする方法

Pythonで入力値をエスケープする場合、入力されるデータのコンテキストに応じて適切なエスケープ手法を選択する必要があります。

以下にいくつかの一般的なケースとその対処方法を示します。

文字列内で特殊文字をエスケープする

以下がエスケープするための基本的な方法です。

  • シングルクォートをエスケープ:バックスラッシュでエスケープ
  • ダブルクォートをエスケープ:ダブルクォートをバックスラッシュでエスケープ
  • バックスラッシュをエスケープ:バックスラッシュをバックスラッシュでエスケープ
  • その他の特殊文字:適切なエスケープシーケンスを使用
input_str = input("Enter a string: ")
escaped_str = input_str.replace("'", "\\'").replace('"', '\\"').replace('\\', '\\\\')

SQLクエリに入力値を組み込む

プレースホルダを使用してSQLクエリを構築し、パラメータとして入力値を渡します。

これによりSQLインジェクション攻撃を防げるのです。

例えば、PythonのDB-APIであるsqlite3モジュールを使用する場合は、プレースホルダを使用します。

import sqlite3

conn = sqlite3.connect("example.db")
c = conn.cursor()

name = input("Enter a name: ")
age = input("Enter an age: ")

c.execute("INSERT INTO users (name, age) VALUES (?, ?)", (name, age))

conn.commit()
conn.close()

HTMLコンテキストで入力値を表示する

入力値をエスケープしてHTMLエンティティに変換。

これにより、HTMLタグや特殊文字が正しく表示されます。

例えば、htmlモジュールのescape関数を使用しましょう。

from html import escape

input_str = input("Enter a string: ")
escaped_str = escape(input_str)

上記の例は一部の一般的なケースですが、入力値をエスケープする方法はコンテキストによって異なります。

対象となるコンテキストに応じて適切なエスケープ手法を選択し、安全かつ適切に入力値を処理するようにしましょう。

literal_eval()関数を使った安全な評価

ast.literal_eval()関数は、eval()の安全な代替手段として用いられます。

これは、文字列、数値、タプル、リスト、および辞書などのPythonリテラルを評価することのみを許可し、任意のコードの実行は許可されません。

import ast

# This is safe
result = ast.literal_eval("{'a': 1, 'b': 2}")
print(result)  # {'a': 1, 'b': 2}

eval()関数を使用する際の注意点

eval()関数を使用する場合は、入力を検証し、不正なコードの実行を防ぐために厳格なサニタイズをおこなう必要があります。

可能な限りliteral_eval()を使用するか、他の安全な代替手段を検討してください。

exec()関数との比較

こちらでは、eval()関数とexec()関数の違いを解説します。

  • exec()関数の概要
  • eval()関数とexec()関数の主な違い
  • 組み込み参照の制限方法

exec()関数の概要

exec()関数はPythonのコードを文字列として受け取り、そのコードを実行します。

ただし、exec()は式の評価結果を返さず、主に文を実行するために使用されます。

code = "x = 5\ny = 2\nprint(x + y)"
exec(code)  # Prints 7

eval()関数とexec()関数の主な違い

主な違いは、eval()関数は式を評価し、その結果を返すのに対して、exec()関数は文を実行し、結果を返しません。

また、exec()は複数行のコードを実行できます。

# eval()関数の例
x = 5
expression = "x * 2"
result = eval(expression)
print(result)  # 出力: 10

# exec()関数の例
code = """
x = 5
y = x + 3
print(y)
"""
exec(code)  # 出力: 8

組み込み参照の制限方法

exec()関数を使用する際も、eval()同様にセキュリティ上のリスクがあります。

組み込み関数や変数への参照を制限することが重要です。

応用: 関数実行やコマンド実行

こちらでは、eval()関数を使用した応用的なテクニックについて解説します。

  • 関数名から実行する方法
  • コマンド実行の例

関数名から実行する方法

eval()関数を使って、関数名の文字列から関数を動的に実行できます。

def greet():
    print("Hello, World!")

function_name = "greet"
eval(function_name + "()")

コマンド実行の例

eval()関数を使って、動的に生成されたコマンドの実行も可能です。

ただし、この方法はセキュリティリスクが高いため、非常に慎重におこないましょう。

command = "print('This is a dynamically executed command')"
eval(command)

まとめ

当記事でお伝えしてきたことは以下のとおりです。

  • eval()関数の基本的な使い方
  • 文字列の評価
  • 数式の評価
  • 引数の使い方
  • 安全性と代替手段

Pythonプログラミングにおいて、この関数を理解し、適切に使用することで、より高度なコーディングが可能になります。

eval()関数は強力ですが、それ故にセキュリティリスクも伴います。

悪意あるコードの実行を防ぐために、eval()関数の使用は慎重に行い、可能な限り安全な代替手段を使用しましょう。

ほかにも多くのテクニックや関数がPythonには存在します。

常に新しい知識を学び、実践を通じてスキルを磨いていくことが重要です。

安全性を意識しながら、有意義なプログラミングライフをお楽しみください。

タイトルとURLをコピーしました