compileall — 字节码编译 Python 库

源代码: Lib/compileall.py


此模块提供了一些实用函数来支持安装 Python 库。这些函数会编译目录树中的 Python 源文件。此模块可用于在库安装时创建缓存的字节码文件,这使得即使对库目录没有写入权限的用户也能使用这些文件。

可用性:非 WASI。

此模块在 WebAssembly 上不起作用或不可用。有关更多信息,请参阅 WebAssembly 平台

命令行使用

此模块可以作为脚本(使用 python -m compileall)来编译 Python 源文件。

directory ...
file ...

位置参数是要编译的文件或包含源文件的目录,将递归遍历。如果没有给出参数,则行为类似于命令行是 -l <directories from sys.path>

-l

不递归进入子目录,只编译命名或隐含目录中直接包含的源文件。

-f

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

-q

不打印已编译文件的列表。如果传递一次,错误消息仍将打印。如果传递两次(-qq),则所有输出都将被抑制。

-d destdir

要编译的每个文件路径前缀的目录。这会出现在编译时回溯中,并也编译到字节码文件中,在源文件在字节码文件执行时不存在的情况下,它将用于回溯和其他消息。

-s strip_prefix

.pyc 文件中记录的路径中移除给定的前缀。路径相对于该前缀。

此选项可与 -p 配合使用,但不能与 -d 配合使用。

-p prepend_prefix

将给定的前缀添加到 .pyc 文件中记录的路径。使用 -p / 使路径变为绝对路径。

此选项可与 -s 配合使用,但不能与 -d 配合使用。

-x 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.process_cpu_count() 的结果。

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

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

-o level

使用给定的优化级别进行编译。可以多次使用以同时编译多个级别(例如,compileall -o 1 -o 2)。

-e dir

忽略指向给定目录之外的符号链接。

如果两个具有不同优化级别的 .pyc 文件具有相同的内容,则使用硬链接合并重复文件。

3.2 版中已更改: 添加了 -i, -b-h 选项。

3.5 版中已更改: 添加了 -j, -r-qq 选项。-q 选项被更改为多级值。-b 将始终生成以 .pyc 结尾的字节码文件,永不生成 .pyo

3.7 版中已更改: 添加了 --invalidation-mode 选项。

3.9 版中已更改: 添加了 -s, -p, -e--hardlink-dupes 选项。将默认递归限制从 10 提高到 sys.getrecursionlimit()。添加了多次指定 -o 选项的可能性。

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

同样,compile() 函数遵循 sys.pycache_prefix 设置。生成的字节码缓存只有在 compile() 运行时使用与运行时相同的 sys.pycache_prefix(如果有)时才有用。

公共函数

compileall.compile_dir(dir, maxlevels=sys.getrecursionlimit(), ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1, invalidation_mode=None, *, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)

递归遍历由 dir 命名的目录树,并编译所有 .py 文件。如果所有文件都成功编译,则返回真值,否则返回假值。

maxlevels 参数用于限制递归的深度;它默认为 sys.getrecursionlimit()

如果给定 ddir,它将被添加到每个被编译的文件路径之前,用于编译时回溯,并且也会被编译到字节码文件中,在源文件在字节码文件执行时不存在的情况下,它将用于回溯和其他消息。

如果 force 为真,即使时间戳是最新的,模块也会被重新编译。

如果给定 rx,其 search 方法将对每个考虑编译的文件的完整路径调用,如果返回真值,则跳过该文件。这可用于排除与正则表达式匹配的文件,该正则表达式以 re.Pattern 对象给出。

如果 quietFalse0(默认),则文件名和其他信息将打印到标准输出。设置为 1,只打印错误。设置为 2,则所有输出都将被抑制。

如果 legacy 为真,则字节码文件将写入其传统位置和名称,这可能会覆盖由其他 Python 版本创建的字节码文件。默认是将文件写入其 PEP 3147 位置和名称,这允许多个 Python 版本的字节码文件共存。

optimize 指定编译器的优化级别。它被传递给内置的 compile() 函数。也接受优化级别序列,这导致在一次调用中对一个 .py 文件进行多次编译。

参数 workers 指定用于并行编译文件的 worker 数量。默认是不使用多个 worker。如果平台不能使用多个 worker 且给定 workers 参数,则将使用顺序编译作为备用方案。如果 workers 为 0,则使用系统中的核心数量。如果 workers 小于 0,则会引发 ValueError

invalidation_mode 应该是 py_compile.PycInvalidationMode 枚举的成员,并控制生成的 pyc 在运行时如何失效。

stripdirprependdirlimit_sl_dest 参数对应于上面描述的 -s-p-e 选项。它们可以指定为 stros.PathLike

如果 hardlink_dupes 为真,并且两个具有不同优化级别的 .pyc 文件具有相同的内容,则使用硬链接合并重复文件。

3.2 版中已更改: 添加了 legacyoptimize 参数。

3.5 版中已更改: 添加了 workers 参数。

3.5 版中已更改: quiet 参数更改为多级值。

3.5 版中已更改: 无论 optimize 的值是什么,legacy 参数都只写入 .pyc 文件,而不写入 .pyo 文件。

在 3.6 版本发生变更: 接受 path-like object

3.7 版中已更改: 添加了 invalidation_mode 参数。

3.7.2 版中已更改: invalidation_mode 参数的默认值更新为 None

3.8 版中已更改: 现在将 workers 设置为 0 会选择最佳核心数。

3.9 版中已更改: 添加了 stripdir, prependdir, limit_sl_desthardlink_dupes 参数。maxlevels 的默认值从 10 更改为 sys.getrecursionlimit()

compileall.compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, invalidation_mode=None, *, stripdir=None, prependdir=None, limit_sl_dest=None, hardlink_dupes=False)

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

如果给定 ddir,它将被添加到被编译文件路径之前,用于编译时回溯,并且也会被编译到字节码文件中,在源文件在字节码文件执行时不存在的情况下,它将用于回溯和其他消息。

如果给定 rx,其 search 方法将传递给被编译文件的完整路径名,如果返回真值,则不编译该文件并返回 True。这可用于排除与正则表达式匹配的文件,该正则表达式以 re.Pattern 对象给出。

如果 quietFalse0(默认),则文件名和其他信息将打印到标准输出。设置为 1,只打印错误。设置为 2,则所有输出都将被抑制。

如果 legacy 为真,则字节码文件将写入其传统位置和名称,这可能会覆盖由其他 Python 版本创建的字节码文件。默认是将文件写入其 PEP 3147 位置和名称,这允许多个 Python 版本的字节码文件共存。

optimize 指定编译器的优化级别。它被传递给内置的 compile() 函数。也接受优化级别序列,这导致在一次调用中对一个 .py 文件进行多次编译。

invalidation_mode 应该是 py_compile.PycInvalidationMode 枚举的成员,并控制生成的 pyc 在运行时如何失效。

stripdirprependdirlimit_sl_dest 参数对应于上面描述的 -s-p-e 选项。它们可以指定为 stros.PathLike

如果 hardlink_dupes 为真,并且两个具有不同优化级别的 .pyc 文件具有相同的内容,则使用硬链接合并重复文件。

在 3.2 版本加入。

3.5 版中已更改: quiet 参数更改为多级值。

3.5 版中已更改: 无论 optimize 的值是什么,legacy 参数都只写入 .pyc 文件,而不写入 .pyo 文件。

3.7 版中已更改: 添加了 invalidation_mode 参数。

3.7.2 版中已更改: invalidation_mode 参数的默认值更新为 None

3.9 版中已更改: 添加了 stripdir, prependdir, limit_sl_desthardlink_dupes 参数。

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 版中已更改: 添加了 legacyoptimize 参数。

3.5 版中已更改: quiet 参数更改为多级值。

3.5 版中已更改: 无论 optimize 的值是什么,legacy 参数都只写入 .pyc 文件,而不写入 .pyo 文件。

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

字节码编译单个源文件。