質問
リストをeval()の関数引数として渡す方法はありますか、それとも文字列に変換してから関数内のリストとして解析する必要がありますか?
私の簡単な例は次のようになります:
eval("func1(\'" + fArgs + "\')")
文字列ではなくリストとしてfArgsを取得するより良い方法があるかどうかはわかりません
注: リストはJSONレスポンスから提供されます
編集:ここでクラスをもう少し詳しく説明します。evalをどのように使用しているかをよりよく理解できます
def test(arg):
print arg
#Add all allowed functions to this list to be mapped to a dictionary
safe_list = ['test']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
class Validate:
def __init__(self, Value, fName, fArgs):
eval(fName + "(\'" + fArgs + "\')", {"__builtins__":None},safe_dict)
これを考えるのは間違っているかもしれませんが、これはevalの安全な使用法です。なぜなら、呼び出すことができる関数はsafe_list辞書にリストされている関数だけだからです。実行される関数とその関数の引数は、JSONオブジェクトから抽出されています。引数はリストとして構成され、&quot ;,"でリストを結合します実際の引数または単一の引数として解釈されますか?
解決
Python 2.6.xを使用している場合は、 json
モジュールを使用できるはずです(py doc 19.2 )。そうでない場合は、pythonパッケージインデックスから python-json を利用できます。これらのパッケージは両方とも、JSONデータを適切なPythonデータ型に解析するためのリーダーを提供します。
メッセージによって決定される関数を呼び出す2番目の問題については、次のことができます。
def foo():
print 'I am foo!'
def bar():
pass
def baz():
pass
funcs = {'func_a':foo, 'func_b':bar, 'func_c':baz}
funcs['func_a']()
このアプローチは、「安全でない」Pythonライブラリ関数がJSONに挿入されるのを防ぐため、 eval
よりも少し安全です。ただし、関数に提供されたデータを操作して問題が発生しないように注意する必要があります。
他のヒント
パラメーターの指定次の方法の動作:
root@parrot$ more test.py
def func1(*args):
for i in args:
print i
l = [1,'a',9.1]
func1(*l)
root@parrot$ python test.py
1
a
9.1
そのため、何かを誤解していない限り、eval()は直接必要ありません。
ライブラリを使用してJSON入力を解析することは、evalよりも優れたアプローチである可能性があります。
import json
func1(json.loads(fArgs))
ユーザー入力が正しいことをアサートすることも良い考えです。
他の人には、 eval
を使用すべきではないという良い点があります。ただし、必要な場合:
eval("func1(%s)" % ", ".join(fArgs))
は、リスト内のすべての引数を使用して関数を呼び出します。これ:
eval("func1([%s])" % ", ".join(fArgs))
は、引数のリストを1つの引数だけで呼び出します。たぶんあなたもこれが欲しいですか?
eval("func1([%s])" % ", ".join(map(eval, fArgs)))
引数も eval
しますか?