如何在Python中执行包含Python代码的string?

如何在Python中执行包含Python代码的string?

对于语句,使用exec(string) (Python 2/3)或exec string (Python 2):

 >>> mycode = 'print "hello world"' >>> exec(mycode) Hello world 

当你需要expression式的值时,使用eval(string)

 >>> x = eval("2+2") >>> x 4 

但是,第一步应该问自己,如果你真的需要。 执行代码通常应该是最后的手段:如果它包含用户input的代码,它是缓慢,丑陋和危险的。 你应该总是先看看替代scheme,比如更高阶的函数,看看这些能否更好地满足你的需求。

在这个例子中,一个string使用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() 

请记住,从版本3 exec是一个function!
所以总是使用exec(mystring)而不是exec mystring

evalexec是正确的解决scheme,并且可以以更安全的方式使用它们。

正如在Python的参考手册中所讨论的,在本教程中已经清楚地解释过, evalexec函数带有两个额外的参数,允许用户指定可用的全局和本地函数和variables。

例如:

 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()仅用于expression式,而eval('x+1')起作用, eval('x=1')不起作用。 在这种情况下,最好使用exec ,甚至更好:尝试find更好的解决scheme:)

使用exec完成执行代码,就像下面的IDLE会话一样:

 >>> kw = {} >>> exec( "ret = 4" ) in kw >>> kw['ret'] 4 

检查评估 :

 x = 1 print eval('x+1') ->2 

避免execeval

在Python中使用execeval是非常令人不悦的。

有更好的select

从最上面的答案(重点是我的):

对于语句,使用exec

当你需要expression式的值时,使用eval

但是,第一步应该问自己,如果你真的需要。 执行代码通常应该是最后的手段 :如果它包含用户input的代码,它是缓慢,丑陋和危险的。 你应该总是先看看替代scheme,比如更高阶的函数 ,看看这些能否更好地满足你的需求。

从替代到执行/评估?

设置并获取string中名称的variables值

[虽然eval ]会起作用,但通常不build议使用带有含义的variables名称给程序本身。

相反,更好地使用字典。

这不是惯用的

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是不安全的,即使你删除所有的全局variables和内部variables!

所有这些保护eval()的尝试都是黑名单 。 他们明确地删除可能是危险的东西。 这是一场失败的战斗,因为如果列表中只剩下一个项目,则可以攻击系统

那么,可以评估安全吗? 很难说。 在这一点上,我最好的猜测是,如果你不能使用任何双下划线,那么你不能做任何伤害,所以也许如果你排除任何string双下划线,你是安全的。 也许…

这很难阅读和理解

http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html (重点是我的):

首先, exec让人们更难阅读你的代码 。 为了弄清楚发生了什么事情,我不仅需要读取代码, 还要读取代码,确定要生成的string,然后读取该虚拟代码。 所以,如果你在一个团队中工作,或者发布开源软件,或者在StackOverflow等地方寻求帮助,那么你就会让其他人更难以帮助你。 如果您有机会在6个月之后debugging或扩展此代码,那么您直接为自己做了更大的努力。

使用eval 。

最合理的解决scheme是使用内置的eval()函数。另一个解决scheme是将该string写入临时的python文件并执行它。

好吧..我知道这不是一个完全的答案,但可能是一个人看我这样的笔记。 我想为不同的用户/客户执行特定的代码,但也想避免exec / eval。 我最初希望将代码存储在每个用户的数据库中,并执行上述操作。

我最终在'customer_filters'文件夹中创build文件系统上的文件,并使用'imp'模块,如果没有filter申请该客户,它只是继续

 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