转载:pyinstaller使用
转载:https://zhuanlan.zhihu.com/p/65731845
pyinstaller最佳使用方式
pyinstaller最重要的两个参数就是-F与-D参数
使用-F参数,pyinstaller会将python脚步打包成单个exe文件
使用-D参数,pyinstaller会将python脚步打包成一个文件夹,运行程序时,需要进入该文件夹,点击运行相应的可执行程序
此前为了美观,开源通过 -i 参数指定程序的icon(图标),但这个命令只在windows下生效,本人MacOS上是没有作用的,同时可以使用 -n 参数定义打包后文件的名称
如果你自己通过PyQt5或tkinter开发了界面,此时通常不希望在运行时弹出命令行,如windows下的cmd命令行,此时可以使用-w参数
综上所述,我最常用的命令为
pyinstall -i xxx.ico -n xxx -w -D main.py
其中 -D 参数或 -F 参数后面跟的是入口文件,即你 python xxx.py
运行程序时这个xxx.py文件
对应依赖比较多的程序,建议使用 -D, -F更适合单文件的py脚本。
pyinstaller 打包其实分两步走,第一步,就是通过上面的命令执行打包,此时会生成相应的spec文件,大体流程如下:
1、在脚本目录生成 xxx.spec 文件(看-n参数,没传,则与xxx.py同名为xxx); 2、创建一个 build 目录; 3、写入一些日志文件和中间流程文件到 build 目录; 4、创建 dist 目录; 5、生成可执行文件或文件夹到 dist 目录;
效果如下:
第一步完成后,获得xxx.spec,然后再执行
pyinstaller xxx.spec
完成打包
进入dist中打包好的文件夹后,双脚运行可执行文件则可
图片上传失败
效果如下:
图片上传失败
这是一个利用tkinter构建界面的简单程序
spec文件解析
一个spec文件的例子。
-
block_cipher =
None
-
a =
Analysis(['minimal.py'],
pathex=['/Developer/PItests/minimal'],
binaries=None,
datas=None,
hiddenimports=[],
hookspath=None,
runtime_hooks=None,
excludes=None,
ciper=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
-
exe = EXE(pyz,
...)
coll = COLLECT(...)
spec文件中主要包含4个class: Analysis, PYZ, EXE和COLLECT.
- Analysis以py文件为输入,它会分析py文件的依赖模块,并生成相应的信息
- PYZ是一个.pyz的压缩包,包含程序运行需要的所有依赖
- EXE根据上面两项生成
- COLLECT生成其他部分的输出文件夹,COLLECT也可以没有
时候PyInstaller自动生成的spec文件并不能满足我们的需求,最常见的情况就是我们的程序依赖我们本地的一些数据文件,这个时候就需要我们自己去编辑spec文件来添加数据文件了。 上面的spec文件解析中Analysis中的datas就是要添加到项目中的数据文件,我们可以编辑datas.
-
a =
Analysis(
...
-
datas =
[('you/source/file/path','file_name_in_project'),
-
('source/file2',
'file_name2')]
...
)
可以认为datas是一个List,每个元素是一个二元组。元组的第一个元素是你本地文件索引,第二个元素是拷贝到项目中之后的文件名字。除了上面那种写法,也可以将其提出来。
-
added_files =
[...]
-
a =
Analysis(
...
datas = added_files,
...
)
这一节内容来自pyinstaller简洁教程
注意事项
避免打包后,包文件过大
为了避免 pyinstaller 打包后程序或文件夹过大,如:几百kb的程序打包后编程500M左右的程序,在引用包时,尽量使用 from ... import ... 语句,这是因为pyinstaller打包的路径其实是将python解释器以及项目中使用的库直接复制过来,所以如果你没事就 import... ,那么pyinstaller会将整个模块复制过去,此时打出来的包就会很大
考虑路径问题
使用python时,要养成使用 os.path.join 的习惯,这不仅可以避免跨平台的路径坑(windows路径表达与类Unix是不同),又可以在打包时不会出现相对路径的问题,很多python程序员编写路径喜欢使用 + 号来链接路径,这会增加项目的维护成本
pyinstaller 打包的项目遇到路径都使用 os.path.join 则可
外部数据问题
虽然在上节中,提及了使用外部数据时,可以自定义 spec 文件中的 datas 字段,但我更常用的做法是直接将数据复制过去,不去修改datas。
比如我的项目中依赖 config 文件夹下的配置文件,执行将 config 文件夹整体直接复制到打包好的文件夹中则可
闪屏结束
如果是简单的程序,可能会出现运行可执行程序后出现一闪而过的情况,这种情况下要么是程序运行结束(比如直接打印的 helloWorld),要么程序出现错误退出了。
这种情况要么通过 input() 函数捕捉输入自己主动结束程序,要么就在 cmd 下运行 exe 文件,从而通过 cmd 看到效果