如何在python中执行包含python代码的字符串?

ao218c7q  于 2021-07-09  发布在  Spark
关注(0)|答案(14)|浏览(293)

如何在python中执行包含python代码的字符串?

ztyzrc3y

ztyzrc3y1#

避免执行和评估

在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是不安全的,即使你删除所有的globals和内置的!
所有这些保护eval()的尝试的问题是它们都是黑名单。它们明确地移除了可能危险的东西。这是一场失败的战斗,因为如果列表中只剩下一项,您就可以攻击系统。
那么,eval安全吗?很难说。在这一点上,我最好的猜测是,如果不能使用任何双下划线,就不会造成任何伤害,因此,如果排除任何带有双下划线的字符串,就可能是安全的。也许 吧。。。

很难阅读和理解

从http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html (我的重点):
第一, exec 使人类更难读懂你的代码。为了弄清楚发生了什么,我不仅要读你的代码,还要读你的代码,弄清楚它将生成什么字符串,然后读虚拟代码。所以,如果你在一个团队工作,或者发布开源软件,或者在stackoverflow这样的地方寻求帮助,你会让其他人更难帮助你。如果6个月后你有机会调试或扩展这段代码,那你就直接让自己更难了。

csga3l58

csga3l582#

正如其他人提到的,是“exec”。。
但是,如果您的代码包含变量,您可以使用“global”来访问它,还可以防止编译器引发以下错误:
nameerror:未定义名称“p\u variable”

exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)
qxsslcnc

qxsslcnc3#

查看评估:

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

cidc1ykv4#

在本例中,使用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()
gzjq41n4

gzjq41n45#

您可以使用exec来完成代码的执行,如以下空闲会话:

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

4
lc8prwob

lc8prwob7#

好 啊。。我知道这不完全是一个答案,但可能是一个注意到人们看这个,因为我是。我希望为不同的用户/客户执行特定的代码,但也希望避免exec/eval。我最初希望为每个用户将代码存储在数据库中并执行上述操作。
最后,我在文件系统的“customer\u 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\u filters\jj\u filter.py文件执行apply\u address\u filter

sh7euo9m

sh7euo9m8#

最合乎逻辑的解决方案是使用内置的eval()函数,另一个解决方案是将该字符串写入一个临时python文件并执行它。

sczxawaw

sczxawaw9#

eval() 只是为了表达,而 eval('x+1') 作品, eval('x=1') 举个例子,这是行不通的。那样的话,最好用 exec ,甚至更好:尝试找到更好的解决方案:)

cotxawn7

cotxawn710#

我尝试了很多方法,但唯一有效的方法是:

temp_dict = {}
exec("temp_dict['val'] = 10") 
print(temp_dict['val'])

输出: 10

e5njpo68

e5njpo6811#

值得一提的是 exec 他的兄弟也存在 execfile 如果要调用python文件。如果您在第三方软件包中工作,其中包含糟糕的ide,并且您希望在其软件包之外编写代码,那么这有时是很好的。
例子: execfile('/path/to/source.py)' 或: exec(open("/path/to/source.py").read())

8cdiaqws

8cdiaqws12#

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

实际上,您是在定义执行代码的命名空间。

qybjjes1

qybjjes113#

还记得第三版吗 exec 是一个函数!
所以一定要用 exec(mystring) 而不是 exec mystring .

icnyk63a

icnyk63a14#

对于语句,使用 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

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

相关问题