在 Python 中,compile()是一个内置函数,用于将字符串或AST对象编译成字节码或代码对象。编译后的字节码或代码对象可以在多个 Python 解释器中执行,从而避免每次执行时重新编译代码。

compile() 函数语法

compile()函数的语法如下:

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)

参数说明:

  • source:必需,表示要编译的源代码。可以是字符串、AST对象或可读取对象。
  • filename:必需,表示源代码的文件名。如果源代码不来自文件,则可以使用一个虚拟文件名。
  • mode:必需,表示编译模式。可以是以下三种值之一:
    • "exec":用于编译包含 Python 语句的代码块,例如模块、函数或类。
    • "eval":用于编译包含单个 Python 表达式的代码块。
    • "single":用于编译包含单个 Python 语句的代码块。
  • flags:可选,表示编译器的标志位。默认值为 0,可以使用多个标志位的按位或运算符组合起来。

    该参数通常不使用,详细用法请查看ast模块的文档;

  • dont_inherit:可选,表示是否从父级作用域中继承标志位。默认值为False
  • optimize:可选,表示优化级别。默认值为 -1,表示使用默认优化级别。可以是以下三个值之一:
    • 0:不进行优化。
    • 1:执行简单优化。
    • 2:执行强制优化。

返回值

返回一个代码对象,可被exec()eval()执行。

示例代码

使用exec模式:

source = "print('hello, world!')"
code = compile(source, "test.py", "exec")

exec(code) # 输出 "hello, world!"

使用eval模式:

a = 5

source = "a * 2 + a"

compiled_expr = compile(source, 'test.py', 'eval')
result = eval(compiled_expr)

print(result)  # 输出: 15

使用flags参数,不编译为字节码,只生成 AST:

import ast

code = """
def foo(a, b):
    return a * b + 5

result = foo(3, 4)
"""

# 只生成 AST,不编译为字节码
ast_object = compile(code, 'test.py', 'exec', flags=ast.PyCF_ONLY_AST)

print("Type:", type(ast_object))
print("AST Content:")
print(ast.dump(ast_object, indent=2))

程序运行结果

Type: <class 'ast.Module'>
AST Content:
Module(
  body=[
    FunctionDef(
      name='foo',
      args=arguments(
        posonlyargs=[],
        args=[
          arg(arg='a'),
          arg(arg='b')],
        kwonlyargs=[],
        kw_defaults=[],
        defaults=[]),
      body=[
        Return(
          value=BinOp(
            left=BinOp(
              left=Name(id='a', ctx=Load()),
              op=Mult(),
              right=Name(id='b', ctx=Load())),
            op=Add(),
            right=Constant(value=5)))],
      decorator_list=[]),
    Assign(
      targets=[
        Name(id='result', ctx=Store())],
      value=Call(
        func=Name(id='foo', ctx=Load()),
        args=[
          Constant(value=3),
          Constant(value=4)],
        keywords=[]))],
  type_ignores=[])