# `compileall` --- 字节编译 Python 库

源代码: Lib/compileall.py

这个模块提供了一些工具函数来支持安装 Python 库。 这些函数可以编译一个目录树中的 Python 源文件。 这个模块可被用来在安装库时创建缓存的字节码文件，这使得它们对于没有库目录写入权限的用户来说也是可用的。

## 使用命令行

此模块可以作为脚本运行 (使用 python -m compileall) 来编译 Python 源代码。

`directory``...`
`file``...`

  位置参数是要编译的文件或包含源文件的目录，目录将被递归地遍历。 如果没有给出参数，则其行为如同使用了命令行 `-l <directories from sys.path>`。

`-l```

  不要递归到子目录，只编译直接包含在指明或隐含的目录中的源代码文件。

`-f```

  强制重新构建即使时间戳是最新的。

`-q```

  不要打印已编译文件的列表。 如果传入一次，则错误消息仍将被打印。 如果传入两次 (`-qq`)，所有输出都会被屏蔽。

`-d` `destdir`

  要附加到每个被编译文件的路径之前的目录。 这将出现在编译时回溯信息中，并且还会被编译到字节码文件中，届时它将在字节码文件被执行而源文件已不存在的情况下被用于回溯和其他消息。

`-x` `regex`

  regex 会被用于搜索每个要执行编译的文件的完整路径，而如果 regex 产生了一个匹配，则相应文件会被跳过。

`-i` `list`

  读取文件 `list` 并将其包含的每一行添加到要编译的文件和目录列表中。 如果 `list` 为 `-`，则从 `stdin` 读取行。

`-b```

  将字节码写入到它们的传统位置和名称，这可能会覆盖由另一版本的 Python 所创建的字节码文件。 默认是将文件写入到它们的 PEP 3147 位置和名称，这允许来自多个版本的 Python 字节码文件共存。

`-r```

  控制子目录的最大递归层级。 如果给出此选项，则 `-l` 选项将不会被考虑。 python -m compileall <directory> -r 0 等价于 python -m compileall <directory> -l。

`-j` `N`

  使用 N 个工作者来编译给定目录中的文件。 如果使用 `0`，则将使用 `os.cpu_count()` 的结果。

`--invalidation-mode``[timestamp|checked-hash|unchecked-hash]`

  控制生成的字节码文件在运行时的失效规则。 值为``timestamp``，意味着将生成嵌入了源时间戳和大小的 `.pyc` 文件。 `checked-hash` 和 `unchecked-hash` 等值将导致生成基于哈希的 pyc。 基于哈希的 pyc 嵌入了源文件内容的哈希值而不是时间戳。 请参阅 已缓存字节码的失效 了解有关 Python 在运行时如何验证字节码缓存文件的更多信息。 如果未设置 `SOURCE_DATE_EPOCH` 环境变量则默认值为 `timestamp`，而如果设置了 `SOURCE_DATE_EPOCH` 则为 `checked-hash`。

3.2 版更變: 增加了 `-i`, `-b` 和 `-h` 选项。

3.5 版更變: 增加了 `-j`, `-r` 和 `-qq` 选项。 `-q` 选项改为多级别值。 `-b` 将总是产生以 `.pyc` 为后缀的字节码文件，而不是 `.pyo`。

3.7 版更變: 增加了 `--invalidation-mode` 选项。

没有可以控制 `compile()` 函数所使用的优化级别的命令行选项，因为 Python 解释器本身已经提供了该选项: python -O -m compileall。

类似地，`compile()` 函数会遵循 `sys.pycache_prefix` 设置。 所生成的字节码缓存将仅当 `compile()` 附带与将在运行时使用的相同 `sys.pycache_prefix` 时可用（如果存在该设置）。

## 公有函数

`compileall.``compile_dir`(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None)

  递归地深入名为 dir 的目录树，在途中编译所有 `.py` 文件。 如果所有文件都编译成功则返回真值，否则返回假值。

  The maxlevels parameter is used to limit the depth of the recursion; it defaults to `10`.

  如果给出了 ddir，它会被附加到每个被编译的文件的路径之前以便在编译时回溯中使用，同时还会被编译到字节码文件中，届时它将在字节码文件被执行而源文件已不存在的情况下被用于回溯和其他消息中。

  如果 force 为真值，则即使时间戳为最新模块也会被重新编译。

  If rx is given, its search method is called on the complete path to each file considered for compilation, and if it returns a true value, the file is skipped.

  如果 quiet 为 `False` 或 `0` (默认值)，则文件名和其他信息将被打印到标准输出。 如果设为 `1`，则只打印错误。 如果设为 `2`，则屏蔽所有输出。

  如果 legacy 为真值，则将字节码文件写入到它们的传统位置和名称，这可能会覆盖由另一版本的 Python 所创建的字节码文件。 默认是将文件写入到它们的 PEP 3147 位置和名称，这允许来自多个版本的 Python 字节码文件共存。

  optimize specifies the optimization level for the compiler. It is passed to the built-in `compile()` function.

  参数 workers 指明要使用多少个工作进程来并行编译文件。 默认设置不使用多个工作进程。 如果平台不能使用多个工作进程而又给出了 workers 参数，则将回退为使用顺序编译。 如果 workers 为 0，则会使用系统的核心数量。 如果 workers 小于 `0`，则会引发 `ValueError`。

  invalidation_mode 应为 `py_compile.PycInvalidationMode` 枚举的成员之一并将控制所生成的 pyc 在运行时以何种方式验证是否失效。

  3.2 版更變: 增加了 legacy 和 optimize 形参。

  3.5 版更變: 增加了 workers 形参。

  3.5 版更變: quiet 形参已改为多级别值。

  3.5 版更變: legacy 形参将只写入 `.pyc` 文件而非 `.pyo` 文件，无论 optimize 的值是什么。

  3.6 版更變: 接受一个 path-like object。

  3.7 版更變: 增加了 invalidation_mode 形参。

  3.7.2 版更變: invalidation_mode 形参的默认值更新为 None。

  3.8 版更變: 将 workers 设为 0 现在将会选择最优核心数量。

`compileall.``compile_file`(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None)

  编译路径为 fullname 的文件。 如果文件编译成功则返回真值，否则返回假值。

  如果给出了 ddir，它会被附加到被编译的文件的路径之前以便在编译时回溯中使用，同时还会被编译到字节码文件中，届时它将在字节码文件被执行而源文件已不存在的情况下被用于回溯和其他消息中。

  If rx is given, its search method is passed the full path name to the file being compiled, and if it returns a true value, the file is not compiled and `True` is returned.

  如果 quiet 为 `False` 或 `0` (默认值)，则文件名和其他信息将被打印到标准输出。 如果设为 `1`，则只打印错误。 如果设为 `2`，则屏蔽所有输出。

  如果 legacy 为真值，则将字节码文件写入到它们的传统位置和名称，这可能会覆盖由另一版本的 Python 所创建的字节码文件。 默认是将文件写入到它们的 PEP 3147 位置和名称，这允许来自多个版本的 Python 字节码文件共存。

  optimize specifies the optimization level for the compiler. It is passed to the built-in `compile()` function.

  invalidation_mode 应为 `py_compile.PycInvalidationMode` 枚举的成员之一并将控制所生成的 pyc 在运行时以何种方式验证是否失效。

  3.2 版新加入.

  3.5 版更變: quiet 形参已改为多级别值。

  3.5 版更變: legacy 形参将只写入 `.pyc` 文件而非 `.pyo` 文件，无论 optimize 的值是什么。

  3.7 版更變: 增加了 invalidation_mode 形参。

  3.7.2 版更變: invalidation_mode 形参的默认值更新为 None。

`compileall.``compile_path`(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1, invalidation_mode=None)

  将在 `sys.path` 中找到的所有 `.py` 文件编译为字节码。 如果所有文件编译成功则返回真值，否则返回假值。

  如果 skip_curdir 为真值（默认），则当前目录不会被包括在搜索中。 所有其他形参将被传递给 `compile_dir()` 函数。 请注意不同于其他编译函数，`maxlevels` 默认为 `0`。

  3.2 版更變: 增加了 legacy 和 optimize 形参。

  3.5 版更變: quiet 形参已改为多级别值。

  3.5 版更變: legacy 形参将只写入 `.pyc` 文件而非 `.pyo` 文件，无论 optimize 的值是什么。

  3.7 版更變: 增加了 invalidation_mode 形参。

  3.7.2 版更變: invalidation_mode 形参的默认值更新为 None。

强制重新编译 `Lib/` 子目录及其所有子目录下的全部 `.py` 文件:

    import compileall

    compileall.compile_dir('Lib/', force=True)

    # Perform same compilation, excluding files in .svn directories.
    import re
    compileall.compile_dir('Lib/', rx=re.compile(r'[/\\][.]svn'), force=True)

    # pathlib.Path objects can also be used.
    import pathlib
    compileall.compile_dir(pathlib.Path('Lib/'), force=True)

也參考

模块 `py_compile`

  将单个源文件编译为字节码。