当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python exec()用法及代码示例


exec() 方法执行动态创建的程序,该程序可以是字符串或代码对象。

exec() 的语法:

exec(object, globals, locals)

参数:

exec() 采用三个参数:

  • object- 字符串或代码对象
  • globals(可选) - 字典
  • locals(可选)- 一个映射对象。字典是 Python 中标准且常用的映射类型。

globalslocals的使用将在本文后面讨论。

返回:

exec() 不返回任何值,它返回 None

示例 1:exec() 如何工作?

program = 'a = 5\nb=10\nprint("Sum =", a+b)'
exec(program)

输出

Sum = 15

这里,字符串对象program 被传递给执行程序的exec()。在这种情况下,globalslocals 被省略。

示例 2:允许用户提供输入

program = input('Enter a program:')
exec(program)

输出

Enter a program: [print(item) for item in [1, 2, 3]]
1
2
3

如果您想从允许多行代码的用户那里获取 Python 代码(使用 '\n' ),您可以在使用 exec() 之前使用 compile() 方法。

了解更多关于compile() method in Python 的信息。

使用exec()时要小心

考虑一种情况,您正在使用 Unix 系统(macOS、Linux 等)并且您已导入 os 模块。 os 模块提供了一种可移植的方式来使用操作系统函数,例如读取或写入文件。

如果您允许用户使用 exec(input()) 输入值,则用户可以使用命令 os.system('rm -rf *') 发出命令来更改文件甚至删除所有文件。

如果您在代码中使用exec(input()),最好检查用户可以使用哪些变量和方法。您可以使用 dir() method 查看哪些变量和方法可用。

from math import *
exec('print(dir())')

输出

['In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__name__', '_dh', '_i', '_i1', '_i2', '_ih', '_ii', '_iii', '_oh', '_sh', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exit', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'get_ipython', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'quit', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

限制 exec() 中可用方法和变量的使用

通常情况下,exec() 中使用的所有可用方法和变量可能都不需要,甚至可能存在安全漏洞。您可以通过将可选的 globalslocals 参数(字典)传递给 exec() 方法来限制这些变量和方法的使用。

1. globals 和 locals 参数都省略

如果两个参数都被省略(如我们前面的示例中所示),则预期由exec() 执行的代码将在当前范围内执行。您可以使用以下代码检查可用的变量和方法:

exec('print(dir())')

2.传递globals参数; locals 参数被省略

globalslocals parameters(字典)分别用于全局变量和局部变量。如果省略locals 字典,则默认为globals 字典。意思是,globals 将用于全局和局部变量。

注意:您可以使用 Python 检查当前的全局和本地字典globalslocals内置方法分别。

3. 将空字典作为全局参数传递

from math import *
exec('print(dir())', {})

# This code will raise an exception
# exec('print(sqrt(9))', {})

如果您将空字典作为 globals 传递,则只有 __builtins__ 可用于 object(exec() 的第一个参数)。即使我们在上面的程序中导入了数学模块,尝试访问 math module 提供的任何函数都会引发异常。

输出

['__builtins__']

使某些方法可用

from math import *
exec('print(dir())', {'sqrt': sqrt, 'pow': pow})

# object can have sqrt() module
exec('print(sqrt(9))', {'sqrt': sqrt, 'pow': pow})

在这里,exec() 执行的代码也可以具有 sqrt()pow() 方法以及 __builtins__

可以根据您的意愿更改方法的名称。

from math import *
exec('print(dir())', {'squareRoot': sqrt, 'pow': pow})

# object can have squareRoot() module
exec('print(squareRoot(9))', {'squareRoot': sqrt, 'pow': pow})

在上述程序中,squareRoot() 计算平方根(类似于 sqrt() 的函数)。但是,尝试使用 sqrt() 会引发异常。

限制内置s的使用

您可以通过将值 None 赋予 globals 字典中的 '__builtins__' 来限制 __builtins__ 的使用。

exec(object, {'__builtins__': None}) 

4. 传递全局和局部字典

您可以通过传递locals 字典使所需的函数和变量可供使用。例如:

from math import *

globalsParameter = {'__builtins__' : None}
localsParameter = {'print': print, 'dir': dir}
exec('print(dir())', globalsParameter, localsParameter)

输出

['dir', 'print']

这里只有两个内置方法print()dir()可以通过exec()方法执行。

请务必注意,exec() 执行代码并且不返回任何值(返回 None )。因此,您不能在函数定义之外使用 return 和 yield 语句。

相关用法


注:本文由纯净天空筛选整理自 Python exec()。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。