2016-10-13 4 views
0

Pythonプログラム内で実行される文字列があり、x [1]、x [2]のような文字列の変数を別のものに変更したい。 以前は2つの引数を持つevalを使用していましたが(2番目はreplaced_word:new_wordのdictです)、今はこのような以前にインポートしたモジュールを使用することができないことに気付きました。だから私がこれを行う場合Python2でインポートされたモジュールを失うことなく辞書でevalを使用

from math import log 
eval(log(x[1], {x[1]: 1}) 

それは、名前のログを認識しないと言うでしょう。 グローバル変数を失うことなく、このようにevalを使用するにはどうすればよいですか? 私は実際にドキュメントの意味を理解できません: https://docs.python.org/2/library/functions.html#eval 説明も役に立ちます。

答えて

1

あなたのグローバル拠点としてglobals()dictをビルドします。

from math import log 

# Copy the globals() dict so changes don't affect real globals 
eval_globals = globals().copy() 
# Tweak the copy to add desired new global 
eval_globals[x[1]] = 1 

# eval using the updated copy 
eval('log(x[1])', eval_globals) 

また、あなたが変更されていないglobals()を使用するようにthree-arg evalを使用するだけでなく、中に、最初にチェック(および修正)されますlocaldictを供給することができます理論的には、後者のアプローチでは、表現が元のグローバルを突然変異させる可能性があるため、addin g .copy()eval('log(x[1])', globals().copy(), {x[1]: 1})にすると、誤ってそのことが起こる危険性が最小限に抑えられます。しかし、病理学的/悪意のあるコードはそれを回避することができます。 evalは結局のところ危険です。どのようにサンドボックス化しても、任意の入力に対しては信頼できません。

+0

グローバルをコピーすることは非常に効率的なようです。私はこの評価を何千回も実行する必要があるだけでなく、毎回それをコピーすると、あまりにも多くのオーバーヘッドが発生するでしょうか? –

+0

@JoaquimFerrer:ちょっと、代替アプローチを追加するための答えを更新していました。その1つは、サンドボックスを少し減らすことを犠牲にして 'globals()' dict'をコピーする必要性をバイパスします。 – ShadowRanger

+0

入力は常に私が作成するので、心配はありません。それは完全にありがとう! –

関連する問題