这是 pyinstaller 打包系列的最后一篇,主要讨论一下修改 .spec
文件,重新打包的高级用法。
pyinstaller 命令的后台流程
我们执行打包命令:
pyinstaller options.. myscript.py
PyInstaller 首先构建一个myscript.spec
文件,spec
是 specification
的缩写,把myscript.spec
理解为打包参数文件,称之为**配置文件” 较好。这个文件默认保存在当前目录下,也可以通过 --specpath
参数指定一个保存目录。
多数情况下,我们直接传递参数给 PyInstaller 执行打包即可,不需要检查或修改打包参数文件,但在一些特殊情况下需要修改 spec
文件。
.spec
文件的用途
.spec
文件实际是一个可执行的 Python 代码,它看起来是这样的:
这个 spec 文件编码了脚本文件名称以及你提供给 pyinstaller
命令的大多数选项,它告诉 Pyinstaller
怎样处理你要打包的脚本。PyInstaller 实际是通过执行spec文件的内容来构建应用程序的。
所以,当我们有一个.spec
文件时,我们可以修改这个文件中的一些参数,再将这个.spec
文件传递给 pyinstaller
命令来重新进行打包,像下面这样:
pyinstaller options name.spec
注意:创建配置文件时,大多数命令选项都被编码到配置文件中。从配置文件构建时,不能更改这些选项。如果它们是在pyinstaller options name.spec
命令行中给出的,则会被忽略,并被spec文件中的选项所替换。
从配置文件构建时,只有以下命令行选项有效:
- –upx-dir
- –distpath
- –workpath
- –noconfirm
- –ascii
- –clean
善用 .spec
文件
在打包应用程序,遇到以下情况时,就需要考虑修改配置文件来解决了:
- 当你想将数据文件与应用程序绑定时。
- 当你想要包含从任何其他来源的运行时库(如 .dll),而 Pyinstaller 不知道这些库的来源时。
- 当您想要将 Python 运行时选项添加到可执行文件时。
- 当您想要创建的应用程序产品由多个程序组成,每个程序可能依赖一组通用的第三方库,当打包这样一个产品时,将每个程序单独与所有依赖捆绑在一起,意味着存储重复的代码和库副本,考虑创建带有合并公共模块的多程序包。
解读.spec
文件
spec
文件就是一个 python 代码文件,下面是一个简短的、最小的、打包成一个文件夹的应用程序的.spec
文件:
block_cipher = None
a = Analysis(['minimal.py'],
pathex=['/Developer/PItests/minimal'],
binaries=None,
datas=None,
hiddenimports=[],
hookspath=None,
runtime_hooks=None,
excludes=None,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,... )
coll = COLLECT(...)
它创建了 4 个类的实例:
- Analysis,
- PYZ,
- EXE
- COLLECT.
Analysis
类实例
输入要打包的脚本文件名列表参数实例化 Analysis
类,它分析这个脚本的所有 import
导入和其它依赖项。
默认将 analysis
实例赋值给变量a
,在类成员命名中包含依赖项的列表:
scripts
: 在命令行中的提供的 python 脚本名称;pure
: 脚本需要的纯 python 模块;pathex
: 用于搜索import
的路径列表,类似使用 [PYTHONPATH
],包括 [--paths
参数给出的路径;binaries
: 脚本需要的非 python 模块,包括--add-binary
参数给出的;datas
: 应用程序中包含的非二进制文件(资源文件),包括--add-data
参数给出的。
PYZ
类实例
PYZ
类实例是一个 .pyz
压缩文档对象,它包含了a.pure
中的所有 Python 模块。你打包环境中的 python 的 base 环境中的 .pyc
文件就会被压缩为一个 .zip
文件:
EXE
类实例
EXE
’ 的实例是从分析的脚本和 PYZ
归档文件构建的。此对象创建可执行文件,其中的参数定义了打包生成的 .exe
文件的名称、图标等属性。
COLLECT
类实例
COLLECT
类实例创建输出的文件夹,其中的参数定义了文件夹名称、包含的文件等。
修改 .spec
文件重新打包的示例
修改我的 .spec
文件,修改以下几个地方:
Analysis
类实例 的datas=['ReadExif小程序使用说明.md'],
添加一个说明文档;EXE
类实例的name='ReadExif_main',
修改为:name='ReadExif',
让生成的执行文件的名称简短点;COLLECT
类实例的name='ReadExif_main')
修改为:`name=‘ReadExifApp’- 保存
- 运行
pyinstaller ReadExif_main.spec
从.spec
文件重新打包一次。(记得先删除此前打包生成的其它文件夹和文件)。
这样,生成的包中,文件夹、exe 文件名称就变得更加友好,文件夹中也包含了 readme.md 说明文档:
pyinstaller 打包的几乎所有选项,都可以在.spec
文件中重新定义,其它的就需要自己取摸索了。
有任何问题,欢迎到 QQ群:457079928, python草堂 交流!