Python exec() 函数用法
2023-09-17 22:27:39
exec()
方法执行作为字符串或代码对象传递的 Python 代码块。该字符串被解析为 Python 语句,然后执行。
语法:
exec(object, globals, locals)
参数:
对象- :(必需)字符串或代码对象。
- globals:(可选)包含全局变量的字典。
- locals:(可选)包含局部变量的字典。
返回值:
没有。
下面的示例演示简单的exec()
方法。
exec('print("Hello World")')
输出:
Hello World
在上面的示例中,'print("Hello World")'
字符串被解析为 Python 语句并执行。
字符串可以是多行代码字符串,其中每行将被视为一个语句,如下所示:
mycode='''a=5
b=4
print('axb=', a*b)'''
exec(mycode)
输出:
axb= 20
传递给 exec()
方法的代码也可以使用 input()
函数获取用户输入。
code = input("Enter Python Expression: ")
exec(code)
输出:
Enter Python Expression: [print(x**2) for x in [1, 2, 3,4,5]]
1
4
9
16
25
默认情况下,exec()
函数可以执行内置函数。例如,下面执行abs()
函数。
exec('print(abs(-9))')
输出:
9
下面的示例显示了在未导入任何模块时可用于exec()
的所有函数。
exec('print(dir())')
输出:
['annotations', 'builtins', 'doc', 'loader', 'name', 'package', 'spec']
您可以在 exec()
方法中传递的代码字符串中导入模块并使用该模块的函数,如下所示。
mycode='''from math import *
a = sqrt(9)
print(a)'''
exec(mycode)
输出:
3.0
如果在调用 exec()
方法(例如 math 模块)之前导入模块,则数学模块的所有方法都可以在 exec()
方法中使用。
from math import *
exec('print(dir())')
输出:
['annotations', 'builtins', 'doc', 'loader', 'name', 'package', 'spec', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
然后,您可以在exec()
中执行导入模块的函数,而无需在代码字符串中包含 import 语句。
from math import *
mycode='''a = sqrt(9)
print(a)'''
exec(mycode)
输出:
3.0
默认情况下,可以在 exec()
方法中使用所有本地、内置和导入模块的函数。使用 globals 参数指定可由 exec()
函数执行的全局、导入模块或内置函数,并使用 locals 参数允许使用本地函数。
例如,即使我们已经导入了sqrt()
函数,以下内容也会限制它的使用。
from math import *
mycode='''a = sqrt(9)
print(a)'''
exec(mycode, {})
输出:
Traceback (most recent call last):
exec(mycode, {})
File "<string>", line 1, in >module>
NameError: name 'sqrt' is not defined
在上面的例子中,我们指定了一个空字典{}
作为全局参数,这表示不允许全局或导入模块的函数,因此在 exec()
函数中调用 sqrt()
函数会抛出错误。
在全局字典中包含 sqrt()
函数以允许在exec()
函数中,如下所示。
from math import *
mycode='''a = sqrt(9)
print(a)'''
exec(mycode, {'sqrt': sqrt})
输出:
3.0
您可以在exec()
函数中添加内置或自定义函数以允许。例如,下面定义了指向sqrt()
函数的sqroot()
函数。
因此,您可以使用sqroot()
函数代替sqrt()
函数。
from math import *
mycode='''a = sqroot(9)
print(a)'''
exec(mycode, {'sqroot': sqrt})
输出:
3.0
还可以通过将值 None 传递给全局字典中的__builtins__
来限制内置函数的使用。下面在调用内置函数 print()
时引发错误。
mycode='print("Hello World")'
exec(mycode, {'__builtins__': None})
输出:
Traceback (most recent call last):
exec(mycode, {'__builtins__': None})
File "<string>", line 1, in >module>
TypeError: 'NoneType' object is not subscriptable
locals
参数用于指定 exec()
方法中允许的局部函数或变量。请考虑以下示例。
def myfunc1():
print('myfunc1')
def myfunc2():
print('myfunc2')
globlsparam = {'__builtins__' : None}
localsparam = {'myfunc1': myfunc1}
exec('myfunc1', globlsparam, localsParameter) # valid
exec('myfunc2', globlsparam, localsparam) # throws error
输出:
myfunc1
Traceback (most recent call last):
exec('myfunc2', globlsparam, localsparam)
File "<string>", line 10, in >module>
NameError: name 'myfunc2' is not defined
在上面的示例中,locals
参数包含一个本地函数myfunc1()
因此exec()
函数可以调用myfunc1()
但不能调用myfunc2()
函数。
因此,我们可以使用全局和局部参数来限制全局和局部函数的使用。