17.12. compileall — 将源码编译为字节码 | 开发者工具 |《python 3 标准库实例教程》| python 技术论坛-380玩彩网官网入口
目的:将源代码文件转换为字节编译的版本。
这个 compileall
模块可以将 python 源代码文件找出来并将他们编译为字节码,之后将结果保存成 .pyc
文件。
编译一个文件夹
这个 compile_dir()
方法用于递归式地扫描一个文件夹并对其中的文件进行字节编译。
compileall_compile_dir.py
import compileall
import glob
def show(title):
print(title)
for filename in glob.glob('examples/**',
recursive=true):
print(' {}'.format(filename))
print()
show('before')
compileall.compile_dir('examples')
show('\nafter')
默认情况下,所有的子文件夹的扫描深度都是 10。输出文件被写入到一个叫做 __pycache__
的文件夹并基于 python 编译器的版本来命名。
$ python3 compileall_compile_dir.py
before
examples/
examples/readme
examples/a.py
examples/subdir
examples/subdir/b.py
listing 'examples'...
compiling 'examples/a.py'...
listing 'examples/subdir'...
compiling 'examples/subdir/b.py'...
after
examples/
examples/readme
examples/a.py
examples/subdir
examples/subdir/__pycache__
examples/subdir/__pycache__/b.cpython-36.pyc
examples/subdir/b.py
examples/__pycache__
examples/__pycache__/a.cpython-36.pyc
忽略不参与编译的文件
若要过滤文件夹,可以使用 rx
参数来提供一个正则表达式用于匹配你想要排除的文件夹的名称。
compileall_exclude_dirs.py
import compileall
import re
compileall.compile_dir(
'examples',
rx=re.compile(r'/subdir'),
)
该版代码可以将名为 subdir
的子文件夹中的文件排除掉。
$ python3 compileall_exclude_dirs.py
listing 'examples'...
compiling 'examples/a.py'...
listing 'examples/subdir'...
其中, maxlevels
参数用于控制递归的深度。比如,想完全避免递归,可以给该参数传入 0
。
compileall_recursion_depth.py
import compileall
import re
compileall.compile_dir(
'examples',
maxlevels=0,
)
只有传给了 compile_dir()
方法的文件夹中的文件才会被编译。
$ python3 compileall_recursion_depth.py
listing 'examples'...
compiling 'examples/a.py'...
编译 sys.path
所有在 sys.path 路径下找到的 python 源代码文件都可以通过对 compile_path()
方法的一次简单调用来进行编译。
compileall_path.py
import compileall
import sys
sys.path[:] = ['examples', 'notthere']
print('sys.path =', sys.path)
compileall.compile_path()
这个例子将 sys.path
的默认内容替换掉用于避免运行脚本时的许可错误,但仍然可以展现出该方法的默认行为。注意, maxlevels
的值默认设为了 0
。
$ python3 compileall_path.py
sys.path = ['examples', 'notthere']
listing 'examples'...
compiling 'examples/a.py'...
listing 'notthere'...
can't list 'notthere'
编译独立文件
若要编译单个文件,而不是一整个文件夹的文件,可使用 compile_file()
方法。
compileall_compile_file.py
import compileall
import glob
def show(title):
print(title)
for filename in glob.glob('examples/**',
recursive=true):
print(' {}'.format(filename))
print()
show('before')
compileall.compile_file('examples/a.py')
show('\nafter')
第一个参数可以是文件名,完整路径或相对路径。
$ python3 compileall_compile_file.py
before
examples/
examples/readme
examples/a.py
examples/subdir
examples/subdir/b.py
compiling 'examples/a.py'...
after
examples/
examples/readme
examples/a.py
examples/subdir
examples/subdir/b.py
examples/__pycache__
examples/__pycache__/a.cpython-36.pyc
在命令行中执行编译
在命令行中调用 compileall
也是可以的,所以这个模块可以通过 makefile 来集成到构建系统中。比如:
$ python3 -m compileall -h
usage: compileall.py [-h] [-l] [-r recursion] [-f] [-q] [-b] [-d
destdir]
[-x regexp] [-i file] [-j workers]
[file|dir [file|dir ...]]
utilities to support installing python libraries.
positional arguments:
file|dir zero or more file and directory names to
compile; if
no arguments given, defaults to the
equivalent of -l
sys.path
optional arguments:
-h, --help show this help message and exit
-l don't recurse into subdirectories
-r recursion control the maximum recursion level. if
`-l` and `-r`
options are specified, then `-r` takes
precedence.
-f force rebuild even if timestamps are up
to date
-q output only error messages; -qq will
suppress the
error messages as well.
-b use legacy (pre-pep3147) compiled file
locations
-d destdir directory to prepend to file paths for
use in compile-
time tracebacks and in runtime
tracebacks in cases
where the source file is unavailable
-x regexp skip files matching the regular
expression; the regexp
is searched for in the full path of each
file
considered for compilation
-i file add all the files and directories listed
in file to
the list considered for compilation; if
"-", names are
read from stdin
-j workers, --workers workers
run compileall concurrently
重新创建下先前的例子,忽略掉 subdir
文件夹,运行:
$ python3 -m compileall -x '/subdir' examples
listing 'examples'...
compiling 'examples/a.py'...
listing 'examples/subdir'...
供参考
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 cc 协议,如果我们的工作有侵犯到您的权益,请及时联系380玩彩网官网入口。