PythonでPythonコードを含む文字列を実行するにはどうすればいいですか?
例では、文字列はexec関数を使ってコードとして実行されます。
import sys
import StringIO
# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()
code = """
def f(x):
x = x + 1
return x
print 'This is my output.'
"""
# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr
exec code
# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
print f(4)
s = codeErr.getvalue()
print "error:\n%s\n" % s
s = codeOut.getvalue()
print "output:\n%s" % s
codeOut.close()
codeErr.close()
ステートメントには、 exec(string)
(Python 2/3)または exec string
(Python 2)を使用してください。
>>> mycode = 'print "hello world"'
>>> exec(mycode)
Hello world
式の値が必要なときは、 eval(string)
を使います。
>>> x = eval("2+2")
>>> x
4
しかし、最初のステップは、本当に必要なのかどうか自分自身に尋ねることです。コードを実行することは、一般的に最後の手段となるべきです。ユーザーが入力したコードが含まれていると、遅くて醜くて危険です。高階関数のような代替手段を常に最初に見て、それらがあなたのニーズをよりよく満たすことができるかどうかを確かめるべきです。
バージョン3からexec
は関数です。
したがって、常にexec mystring
ではなくexec(mystring)
を使用してください。
eval
とexec
は正しい解決方法であり、より安全な方法で使用できます。
Pythonのリファレンスマニュアル で説明され、 this チュートリアルで明確に説明されているように、eval
およびexec
関数は2つの追加パラメータを使用利用可能です。
例えば:
public_variable = 10
private_variable = 2
def public_function():
return "public information"
def private_function():
return "super sensitive information"
# make a list of safe functions
safe_list = ['public_variable', 'public_function']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
# add any needed builtins back in
safe_dict['len'] = len
>>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
12
>>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_variable' is not defined
>>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
'public information' has 18 characters
>>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_function' is not defined
要するに、あなたはコードが実行される名前空間を定義しているのです。
eval()
は式専用ですが、eval('x+1')
は機能しますが、eval('x=1')
は機能しません。その場合は、exec
を使用することをお勧めします。それよりも優れています。より良い解決策を見つけるようにしてください:)
次のIDLEセッションのように、execを使用してコードを実行します。
>>> kw = {}
>>> exec( "ret = 4" ) in kw
>>> kw['ret']
4
exec
とeval
は避けてくださいexec
とeval
を使用することは非常に嫌です。トップの答えから(私の強調点):
文の場合は
exec
を使用してください。式の値が必要なときは
eval
を使用してください。しかし、最初のステップは、本当に必要なのかどうか自分自身に尋ねることです。 コードを実行することは、一般的に最後の手段になるはずです:ユーザーが入力したコードが含まれていると、遅くて醜くて危険です。あなたは常に高次関数のような最初の選択肢を最初に見て、それらがあなたのニーズをよりよく満たすことができるかどうかを確かめるべきです。
From exec/evalの代わりに?
文字列内の名前で変数の値を設定および取得する
[
eval
]は機能しますが、プログラム自体に意味を持つ変数名を使用することはお勧めできません。代わりに、辞書を使用してください。
http://lucumr.pocoo.org/2011/2/1/exec- in-python /から (強調私のもの)
PythonはPHPではありません
他の言語では違った方法でPythonのイディオムを迂回しようとしないでください。名前空間はPythonには理由があり、それはあなたに
exec
というツールを与えるという理由だけでそれはあなたがそのツールを使うべきであるという意味ではありません。
http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html から(強調表示)
そのため、すべてのグローバルとビルトインを削除しても、evalは安全ではありません。
Eval()を保護しようとするこれらの試みすべての問題は、それらがブラックリストであるということです。彼らは明らかに危険かもしれないものを削除します。 リストから1つだけアイテムが残っていると、システムを攻撃できるので、これは負けた戦いです。
だから、評価は安全にすることができますか?言いにくい。現時点では、二重下線を使用できない場合は害を及ぼすことはできないと思われるので、二重下線を含む文字列を除外しても安全です。多分...
http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html から(強調表示)
まず、
exec
は、人間がコードを読むのを難しくします。何が起こっているのかを理解するために、私はあなたのコードを読む必要はありません。私はあなたのコードを読み、それがどの文字列を生成しようとしているか考えます。 つまり、チームで作業している場合、またはオープンソースソフトウェアを公開している場合、あるいはStackOverflowのような場所で支援を求めている場合は、他の人があなたを支援するのが難しくなります。そして、今から6か月後にこのコードをデバッグしたり拡張したりする可能性がある場合は、直接それを困難にしています。
チェックアウト eval :
x = 1
print eval('x+1')
->2
eval を使ってください。
最も論理的な解決策は組み込みの eval() 関数を使うことです。もう一つの解決策はその文字列を一時的なpythonファイルに書いて実行することです。
Pythonファイルを呼び出したい場合は、exec
name __の兄弟がexecfile
name__と同じ名前で存在することを言及する価値があります。ひどいIDEが含まれているサードパーティのパッケージで作業していて、それらのパッケージの外側でコーディングしたいのであれば、それは良いことです。
例:
execfile('/path/to/source.py)'
または:
exec(open("/path/to/source.py").read())
他の人が言ったように、それは "exec"です..
ただし、コードに変数が含まれている場合は、「global」を使用してそれにアクセスできます。また、コンパイラが次のエラーを発生させないようにすることもできます。
NameError:名前 'p_variable'は定義されていません
exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)
わかりました。私はこれがまさに答えではないことを知っています、しかし私がそうであったようにこれを見ている人々のための多分メモ。私は異なるユーザー/顧客のために特定のコードを実行したいと思いましたが、exec/evalを避けたいと思いました。私は最初に各ユーザーのためにデータベースにコードを保存して、上記をすることに目を向けました。
ファイルシステム上の「customer_filters」フォルダー内にファイルを作成し、「imp」モジュールを使用しました。その顧客にフィルターが適用されていない場合は、そのまま続行しました
import imp
def get_customer_module(customerName='default', name='filter'):
lm = None
try:
module_name = customerName+"_"+name;
m = imp.find_module(module_name, ['customer_filters'])
lm = imp.load_module(module_name, m[0], m[1], m[2])
except:
''
#ignore, if no module is found,
return lm
m = get_customer_module(customerName, "filter")
if m is not None:
m.apply_address_filter(myobj)
したがって、customerName = "jj"はcustomer_filters\jj_filter.pyファイルからapply_address_filterを実行します。