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

2024-04-19 11:26:04 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
3条回答

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

正如在Python's reference manual中讨论并在this教程中清楚说明的,evalexec函数采用两个额外参数,允许用户指定可用的全局和局部函数和变量。

例如:

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

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

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

对于语句,请使用^{}(Python 2/3)或^{}(python2):

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

当需要表达式的值时,请使用^{}

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

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

相关问题 更多 >