29.2. codeop — 编译 Python 代码 — Python 文档
29.2. 代码操作 — 编译 Python 代码
codeop 模块提供了可以模拟 Python read-eval-print 循环的实用程序,就像在 code 模块中所做的那样。 因此,您可能不想直接使用该模块; 如果你想在你的程序中包含这样一个循环,你可能想使用 code 模块来代替。
这项工作有两个部分:
- 能够判断一行输入是否完成了 Python 语句:简而言之,判断接下来是打印 '
>>>
' 还是 '...
'。 - 记住用户输入了哪些未来的语句,以便后续的输入可以在这些语句生效的情况下进行编译。
codeop 模块提供了一种方法来完成这些事情中的每一个,以及一种同时完成它们的方法。
只做前者:
- codeop.compile_command(source[, filename[, symbol]])
尝试编译 source,它应该是一串 Python 代码,如果 source 是有效的 Python 代码,则返回一个代码对象。 在这种情况下,代码对象的文件名属性将为 文件名 ,默认为
'<input>'
。 如果 source 是 不是 有效的 Python 代码,但它是有效 Python 代码的前缀,则返回None
。如果source有问题,会抛出异常。
SyntaxError
如果存在无效的 Python 语法,则会引发;如果存在无效文字,则会引发OverflowError
或ValueError
。symbol 参数确定是将 source 编译为语句(
'single'
,默认值)还是编译为 表达式('eval'
])。 任何其他值都会导致ValueError
升高。笔记
解析器有可能(但不太可能)在到达源的末尾之前停止解析并获得成功的结果; 在这种情况下,可以忽略尾随符号而不是导致错误。 例如,反斜杠后跟两个换行符可能后跟任意垃圾。 一旦解析器的 API 更好,这将得到修复。
- class codeop.Compile
- 此类的实例具有与内置函数 compile() 签名相同的
__call__()
方法,但不同之处在于,如果实例编译包含 __future__ 的程序文本] 语句,实例“记住”并编译所有后续程序文本,并使用有效的语句。
- class codeop.CommandCompiler
- 此类的实例具有与 compile_command() 签名相同的
__call__()
方法; 不同之处在于,如果实例编译包含__future__
语句的程序文本,则实例会“记住”并使用有效的语句编译所有后续程序文本。
关于版本兼容性的说明:Compile 和 CommandCompiler 是 Python 2.2 中的新功能。 如果您想启用 2.2 的未来跟踪功能,但又要保持与 2.1 和更早版本的 Python 的兼容性,您可以编写
try:
from codeop import CommandCompiler
compile_command = CommandCompiler()
del CommandCompiler
except ImportError:
from codeop import compile_command
这是一个影响很小的更改,但可能会在您的程序中引入不需要的全局状态,或者您可以编写:
try:
from codeop import CommandCompiler
except ImportError:
def CommandCompiler():
from codeop import compile_command
return compile_command
然后每次需要新的编译器对象时调用 CommandCompiler
。