29.2. codeop — 编译 Python 代码 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/codeop
跳转至:导航、​搜索

29.2. 代码操作 — 编译 Python 代码

codeop 模块提供了可以模拟 Python read-eval-print 循环的实用程序,就像在 code 模块中所做的那样。 因此,您可能不想直接使用该模块; 如果你想在你的程序中包含这样一个循环,你可能想使用 code 模块来代替。

这项工作有两个部分:

  1. 能够判断一行输入是否完成了 Python 语句:简而言之,判断接下来是打印 '>>>' 还是 '...'。
  2. 记住用户输入了哪些未来的语句,以便后续的输入可以在这些语句生效的情况下进行编译。

codeop 模块提供了一种方法来完成这些事情中的每一个,以及一种同时完成它们的方法。

只做前者:

codeop.compile_command(source[, filename[, symbol]])

尝试编译 source,它应该是一串 Python 代码,如果 source 是有效的 Python 代码,则返回一个代码对象。 在这种情况下,代码对象的文件名属性将为 文件名 ,默认为 '<input>'。 如果 source不是 有效的 Python 代码,但它是有效 Python 代码的前缀,则返回 None

如果source有问题,会抛出异常。 SyntaxError 如果存在无效的 Python 语法,则会引发;如果存在无效文字,则会引发 OverflowErrorValueError

symbol 参数确定是将 source 编译为语句('single',默认值)还是编译为 表达式'eval' ])。 任何其他值都会导致 ValueError 升高。

笔记

解析器有可能(但不太可能)在到达源的末尾之前停止解析并获得成功的结果; 在这种情况下,可以忽略尾随符号而不是导致错误。 例如,反斜杠后跟两个换行符可能后跟任意垃圾。 一旦解析器的 API 更好,这将得到修复。

class codeop.Compile
此类的实例具有与内置函数 compile() 签名相同的 __call__() 方法,但不同之处在于,如果实例编译包含 __future__ 的程序文本] 语句,实例“记住”并编译所有后续程序文本,并使用有效的语句。
class codeop.CommandCompiler
此类的实例具有与 compile_command() 签名相同的 __call__() 方法; 不同之处在于,如果实例编译包含 __future__ 语句的程序文本,则实例会“记住”并使用有效的语句编译所有后续程序文本。

关于版本兼容性的说明:CompileCommandCompiler 是 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