问题:如何在Python中执行包含Python代码的字符串?
如何在Python中执行包含Python代码的字符串?
回答 0
对于语句,请使用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
但是,第一步应该是问自己是否真的需要。通常,执行代码应该是最后的选择:如果代码中可能包含用户输入的代码,则它很慢,很丑陋而且很危险。您应该始终首先考虑替代项,例如高阶函数,以查看它们是否可以更好地满足您的需求。
回答 1
在示例中,使用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()
回答 2
eval
并且exec
是正确的解决方案,它们可以被用在更安全方式。
正如Python参考手册中所讨论并在本教程中明确说明的那样,eval
和exec
函数使用两个额外的参数,这些参数允许用户指定可用的全局和局部函数和变量。
例如:
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
本质上,您是在定义将在其中执行代码的命名空间。
回答 3
请记住,从版本3开始exec
是一个功能!
因此请始终使用exec(mystring)
代替exec mystring
。
回答 4
eval()
仅用于表达,虽然eval('x+1')
有效,但eval('x=1')
不会起作用。在这种情况下,最好使用exec
,甚至更好:尝试找到更好的解决方案:)
回答 5
避免exec
和eval
在Python中使用exec
和eval
受到了极大的反对。
有更好的选择
从最上面的答案(强调我的):
对于语句,请使用
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()的问题都在于它们是黑名单。他们明确删除了可能危险的内容。那是一场失败的战斗,因为如果只剩下一个项目,那么您可以攻击系统。
那么,可以使eval安全吗?很难说。在这一点上,我最好的猜测是,如果您不能使用任何双下划线,那么不会造成任何伤害,因此,如果您排除任何具有双下划线的字符串,那么您是安全的。也许…
很难阅读和理解
来自http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html(重点是我):
首先,
exec
使人类更难阅读您的代码。为了弄清楚发生了什么,我不仅要阅读您的代码,还必须阅读您的代码,弄清楚它将生成什么字符串,然后阅读该虚拟代码。因此,如果您在团队中工作,发布开源软件或在StackOverflow之类的地方寻求帮助,那么其他人将很难为您提供帮助。而且,如果您有机会在6个月后进行该代码的调试或扩展,那么直接给自己增加难度。
回答 6
您可以使用exec完成执行代码,就像下面的IDLE会话一样:
>>> kw = {}
>>> exec( "ret = 4" ) in kw
>>> kw['ret']
4
回答 7
正如其他人提到的那样,它是“ exec” ..
但是,如果您的代码包含变量,则可以使用“全局”来访问它,还可以防止编译器引发以下错误:
NameError:名称“ p_variable”未定义
exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)
回答 8
使用eval。
回答 9
值得一提的是,如果您要调用python文件,则该exec
兄弟也存在execfile
。如果您使用的第三方程序包中包含糟糕的IDE,并且您想在其程序包之外进行编码,那有时会很好。
例:
execfile('/path/to/source.py)'
要么:
exec(open("/path/to/source.py").read())
回答 10
查看eval:
x = 1
print eval('x+1')
->2
回答 11
我尝试了很多事情,但是唯一可行的事情如下:
temp_dict = {}
exec("temp_dict['val'] = 10")
print(temp_dict['val'])
输出:
10
回答 12
最合乎逻辑的解决方案是使用内置的eval()函数。另一种解决方案是将该字符串写入临时python文件并执行。
回答 13
好吧..我知道这不是一个确切的答案,但可能是对像我一样看这个问题的人的注释。我想为不同的用户/客户执行特定的代码,但也想避免执行/评估。我最初希望将代码存储在每个用户的数据库中,然后执行上述操作。
我最终在“ 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