将eval与字典一起使用而不会丢失Python2中的导入模块

时间:2016-10-13 19:51:06

标签: python eval python-2.x

我有一个在我的python程序中执行的字符串,我想将字符串中的一些变量(如x [1],x [2])更改为其他内容。 我之前使用过带有2个参数的eval(第二个是带有replacement_word的字典:new_word)但是现在我注意到我不能使用像这样的先前导入的模块。所以,如果我这样做

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

它会说它无法识别名称日志。 如何在不丢失全局变量的情况下使用这样的eval? 我真的无法理解文档: https://docs.python.org/2/library/functions.html#eval 所以解释也很有用。

1 个答案:

答案 0 :(得分: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)

或者,您可以使用three-arg eval使用globals()未经修改,但也提供local s dict,将首先检查(和修改),优先选择全球价值观:

eval('log(x[1])', globals(), {x[1]: 1})

理论上,后一种方法可以允许表达式改变原始全局变量,因此添加.copy()使其成为eval('log(x[1])', globals().copy(), {x[1]: 1})可以最大限度地减少意外发生的风险。但病态/恶意代码可以解决这个问题; eval毕竟是危险的,无论你做出多少沙箱,都不要相信任意输入。