在 Python 中,compile() 是一个内置函数,用于将源代码(字符串、AST 对象)编译为可执行的代码对象(code object)或 AST 对象。这个功能为动态执行代码、元编程和编译器开发提供了底层支持。以下是其核心功能和使用方法的详细介绍:
compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
参数说明:
source:待编译的源代码(字符串、AST 对象)。
filename:代码文件的名称(如果不是从文件读取,可自定义,如 <string>)。
mode:编译模式,决定代码的类型和执行方式:
'exec':用于执行模块、类或多条语句(允许包含多个语句)。
'eval':用于单个表达式求值(返回结果)。
'single':用于单个交互式语句(如 Python 解释器中的单行输入)。
flags 和 dont_inherit:控制编译时的语法特性(如 from __future__ import division)。
optimize:优化级别(-1 为默认,0 为无优化,1 为正常优化,2 为更激进优化)。
将字符串形式的代码编译后执行:
code = "x = 5; y = 10; print(x + y)"
compiled = compile(code, "<string>", "exec")
exec(compiled)
使用 eval() 执行编译后的表达式:
expression = "3 * 4 + 5"
compiled = compile(expression, "<string>", "eval")
result = eval(compiled)
支持单行交互式代码的编译与执行:
code = "print('Hello, World!')"
compiled = compile(code, "<string>", "single")
exec(compiled)
通过指定 optimize 参数生成优化后的代码:
code = "def add(a, b): return a + b"
compiled = compile(code, "<string>", "exec", optimize=2)
exec(compiled)
print(add(3, 4))
结合 ast 模块处理抽象语法树:
import ast
source = "x = 1 + 2"
tree = ast.parse(source)
compiled = compile(tree, "<string>", "exec")
exec(compiled)
print(x)
| 模式 | 适用场景 | 示例代码 |
'exec' |
模块、类、多条语句 |
a = 1; b = 2; print(a + b) |
'eval' |
单个表达式 |
3 * 4 + 5 |
'single' |
交互式单行语句(支持 print) |
x = 1; print(x) |
对于需要多次执行的代码,预编译可提高性能:
code = "sum([i for i in range(1000)])"
compiled = compile(code, "<string>", "eval")
通过 flags 参数启用未来语法:
from __future__ import division
import ast
code = "1/2"
在不可信代码执行场景中,结合 ast 模块过滤危险操作:
import ast
class RestrictedVisitor(ast.NodeVisitor):
def visit_Import(self, node):
raise RuntimeError("Import statements not allowed")
执行动态编译的代码可能导致安全漏洞(如代码注入),应避免执行不可信的输入。
编译操作本身有开销,仅对需要多次执行的代码进行预编译才有性能提升。
- 使用
'exec' 处理多行代码,'eval' 处理表达式,'single' 处理交互式语句。
- 错误的模式会导致
SyntaxError(如用 'eval' 编译多行代码)。
eval() 和 exec() 可直接接受字符串代码,但内部会先调用 compile()。
- 显式使用
compile() 可分离编译和执行步骤,适合需要复用编译结果的场景。
compiled = compile("3 + 4", "<string>", "eval")
result = eval(compiled)
compile() 函数的核心价值在于:
- 动态代码执行:将字符串或 AST 转换为可执行对象。
- 性能优化:预编译多次使用的代码。
- 元编程:在运行时操作和生成代码。
但需谨慎使用,避免安全风险。常见场景包括:动态配置加载、代码生成工具、自定义解释器等。