Pythonにeval()
関数があります。遊んでいるときに偶然見つけました。この関数が必要な場合は、おそらくシンタックスシュガーとして以外は考えられません。例?
eval
とexec
は、いくつかのソースコードを動的に取得し、少し変更してから実行するための便利で迅速な方法ですが、特に「迅速な」ではなく本番用コードでは、最善の方法とは言えません。 and-dirty "プロトタイプ&c。
たとえば、このような動的なPythonソースを処理する必要がある場合、 ast モジュールに到達すると思います-_ast.literal_eval
_はeval
よりはるかに安全です(1回限りで単純な定数のみに依存している場合は、式の文字列形式で直接呼び出すことができます。または、最初にnode = ast.parse(source)
を実行し、次にnode
を保持してください。適切な訪問者と変更してください。たとえば、変数ルックアップの場合は、次に_literal_eval
_ the node)-または、ノードを適切な形状にしてセキュリティの問題を検証した後、compile
it(コードオブジェクトを生成)して新しい関数オブジェクトを作成できますそれほど単純ではありません(ただし、_ast.literal_eval
_は、eval
と同じくらい単純ですが、最も単純な場合です)。しかし、本番品質のコードでは、より安全で望ましいです。
多くのタスクで、exec
とeval
のようなgetattr
とsetattr
を(ab-)使用して、globals()
へのインデックス付けと&cでPythonの強力なビルトインを使用することで、より簡単なソリューションを提供しています。 JSONの解析などの特定の用途には、json
などのライブラリモジュールの方が適しています(たとえば、この質問に対する耳鳴りの答えに関するSilentGhostのコメントを参照してください)。などなど...
ウィキペディアのeval
に関する記事はかなり参考になり、さまざまな使用法について詳しく説明しています。
それが示唆する用途のいくつかは次のとおりです。
これを使用して、ユーザーが独自の「スクリプトレット」を入力できるようにすることができます:small式(または小さな関数でも)complex =システム。
[。
以前は、eval()を使用して、アプリケーションにデバッグインターフェイスを追加しました。実行中のアプリケーションの環境にドロップするtelnetサービスを作成しました。入力はeval()を介して実行されたため、アプリケーションで対話的にPythonコマンドを実行できます。
私がかつて書いたプログラムでは、値とpython以前の値の式の両方として)として幾何学的パラメーターを指定できる入力ファイルがありました。例:
a=10.0
b=5.0
c=math.log10(a/b)
A pythonパーサーはこの入力ファイルを読み取り、eval()を使用して値と式を評価する最終データを取得しました。
良いプログラミングだとは言いませんが、原子炉を運転する必要はありませんでした。
クイックJSONパーサーとして使用しています...
r='''
{
"glossary": {
"title": "example glossary"
}
}
'''
print eval(r)['glossary']['title']
eval()
は通常、あまり役に立ちません。私がそれを使用した数少ないものの1つ(まあ、実際にはexec()
でしたが、それはかなり似ています)は、ユーザーがPythonで記述したアプリケーションをスクリプト化できるようにしました。 C++のようなもので書かれた場合、Pythonインタプリタをアプリケーションに埋め込む必要があります。
Evalは、プログラム内からPythonインタプリタと対話する方法です。リテラルをevalに渡すことができ、それをpython式として評価します。
例えば -
print eval("__import__('os').getcwd()")
現在の作業ディレクトリを返します。
乾杯
デコレータでevalを使うことができます:
#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
@eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
print("The number is %i", i)
#call
printNumber()
次のような複雑な式は使用できませんが
@lambda fun: lambda: fun(10)
def ...
また
@(lambda fun: lambda: fun(10))
def ...
ここではラムダ式を使用することはできません。デコレータは識別子である必要があるためです。
@myModule.functionWithOneArg
または関数呼び出し:
@functionReturningFunctionWithOneArg(any, "args")
文字列を使用した関数evalの呼び出しには有効な構文がありますが、lambda-expressionにはありません。 (-> https://docs.python.org/3/reference/compound_stmts.html#function-definitions )
eval()は単一の文用であり、exec()は複数の文用です。
通常は、bash Shellと同じようにスクリプトを追加または訪問するためにそれらを使用します。
メモリ内でいくつかのバイトスクリプトを実行できるため、重要なデータやスクリプトがある場合は、「秘密」をデコードして解凍し、やりたいことをすべて実行できます。
私はそれを使用して、メインプログラムに変数値を入力しました。
test.py var1 = 2 var2 = True
...
var1=0
var2=False
for arg in sys.argv[1:]:
exec(arg)
メインプログラムでキーワード引数を許可する大雑把な方法。より良い方法がある場合はお知らせください!
私はevalの良い使い方を見つけました。いくつかのコードのテストスイートを作成していて、すべてのメソッドが実行されるテストであるTestクラスを作成しました。各メソッドを個別に呼び出す必要なく、すべてのテストメソッドを実行できる方法が必要でした。だから、私はかなり汚いものを書いた。
class Test:
def __init__(self, *args):
#bs
def test1(self):
#bs
def test2(self):
#bs
if __name__ == "__main__":
import argparse
#argparse bs
test = Test(*bs_args)
for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
print(eval('test.{func}()'.format(func = func)))
任意のテストケースの動的評価は非常に優れています。メソッドを記述するだけで、保存後、メソッドをテストスイートに含めることができます。コードについては、基本的にはテストオブジェクトで定義されたメソッドを調べ、それらがデフォルトでないことを確認しますpython "magic"メソッドまたはTestオブジェクトの属性です。その後、それらはメソッドであり、評価できると仮定します。