ZetCode

Python exec 函数

上次修改时间:2025 年 4 月 11 日

这份全面的指南探讨了 Python 的 exec 函数,该函数执行动态创建的代码。我们将涵盖语法、作用域处理、安全注意事项以及动态执行的实际示例。

基本定义

exec 函数从字符串或代码对象动态执行 Python 代码。它可以修改当前命名空间并执行复杂的代码块。

主要特点:将源代码作为字符串,在给定的命名空间中执行,返回 None,并且可以根据上下文影响局部/全局变量。

基本字符串执行

这是一个简单的用法示例,展示了 exec 如何从字符串执行 Python 代码并修改当前命名空间。

basic_exec.py
code = """
x = 10
y = 20
print(x + y)
"""

exec(code)  # Outputs: 30

# Variables are now in the namespace
print(x)    # 10
print(y)    # 20

此示例显示 exec 执行一个多行代码字符串。该代码创建变量并执行影响当前作用域的操作。

执行后,变量 x 和 y 在当前命名空间中可用,这证明了 exec 修改环境的能力。

使用命名空间控制作用域

exec 可以在特定的命名空间中执行代码,以控制变量的访问和修改。此示例展示了如何使用自定义字典。

scope_control.py
global_ns = {}
local_ns = {}

code = """
a = 1
b = 2
print(a + b)
"""

exec(code, global_ns, local_ns)

print("Global:", global_ns)  # Contains builtins
print("Local:", local_ns)    # Contains a and b

这将在隔离的命名空间中执行代码。全局命名空间包含内置函数,而局部命名空间包含已执行代码的变量。

此技术对于沙箱环境或者当您需要控制哪些变量被执行的代码修改时非常有用。

动态函数创建

exec 可以在运行时动态创建函数。此示例展示了如何从字符串生成和使用函数。

dynamic_function.py
func_code = """
def dynamic_multiply(x, y):
    return x * y
"""

exec(func_code)

result = dynamic_multiply(5, 7)
print(result)  # 35

代码字符串定义了一个函数,exec 使该函数在当前命名空间中可用。然后,我们可以像调用任何常规函数一样调用它。

这演示了如何将 exec 用于元编程和运行时代码生成场景。

安全注意事项

此示例演示了使用 exec 处理未经处理的输入的危险以及如何降低风险。

security.py
# Dangerous example (never do this with user input!)
user_input = "__import__('os').system('rm -rf /')"
try:
    exec(user_input)
except:
    print("Prevented dangerous operation")

# Safer alternative with restricted globals
safe_globals = {'__builtins__': None}
exec("print('Safe code')", safe_globals)

第一部分展示了如果提供不受信任的输入,exec 如何执行危险代码。第二部分演示了使用受限全局变量的安全执行方法。

使用 exec 时,始终验证和清理输入,或者完全避免使用用户提供的代码。

模板处理

exec 可以通过将变量注入到代码字符串中来用于简单的模板处理。

templates.py
template = """
for i in range({count}):
    print(f"Item {i+1}/{count}")
"""

context = {'count': 3}
exec(template.format(**context))

此示例展示了一个基本的模板系统,我们在执行之前将变量注入到代码模板中。格式化的字符串变为有效的 Python 代码。

虽然不建议用于复杂的模板(请改用专用库),但它演示了 exec 在代码生成方面的灵活性。

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。 我在编程教学方面拥有超过十年的经验。

列出所有 Python 教程