你好,我是悦创。
一直有读者在后台问有关 Python 脚本打包成 exe 的问题。
今天就给大家全面总结一下:Python 如何打包成 exe,以及如何打得足够小。
标准打包
目前比较常见的打包 exe 方法都是通过 Pyinstaller
来实现的,本文也将使用这种常规方法。如果对这块已经很熟悉的小伙伴,可以直接下滑到本文下半部分。
为什么要打包?
众所周知,Python 脚本不能在没有安装 Python 的机器上运行。
那我们如果写了一个数据分析/自动化办公的小脚本,想分享给同事小姐姐使用,可她电脑又没有装 Python 。
这个时候如果将脚本打包成 exe 文件,微信发送给她,即使她的电脑上没有安装 Python 解释器,这个 exe 程序也能在上面运行。岂不美哉?
(当然,想通过帮安装Python跟小姐姐建立感情的话,就当我没说)
安装 Pyinstaller
首先我们要先安装 Pyinstaller,直接在 cmd 使用 pip 命令
pip install pyinstaller
如果网速太慢可以切换国内源来加速,本文其他部分直接使用国内源,不再重复注释。
一条命令就可以换源:
pip config set global.index-url https://pypi.douban.com/simple
当然,我们还可以直接使用:
pip install -i https://pypi.douban.com/simple/ pyinstaller #豆瓣源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller #清华源
Pyinstaller 打包步骤
这里我拿飞机大战的代码来做演示,如果你需要可以点击此链接获取:https://github.com/AndersonHJB/Pygame-aircraft-battle
1、cmd 切换到我们刚刚放文件的目录
2、执行命令
Pyinstaller -F -w main.py
执行过程特别漫长,就没有录制动图。
执行完毕会发现当前目录多了几个文件夹,打开其中名为 dist 的文件夹。
已经生成了一个名为 main 的 exe 应用程序,看来已经成功一半了。自行运行是否成功。
成功运行,可惜就是文件有点大(13.4M)
3. Pyinstaller 参数详解
说回刚刚执行的命令
Pyinstaller -F -w main.py
给大家解释一下其中 Pyinstaller 的参数,其中 -F
参数代表制作独立的可执行程序。
-w
是指程序启动的时候不会打开命令行。如果不加 -w
的参数,就会有黑洞洞的控制台窗口出来。比如在刚才的脚本里我加一行 print('Hello World!')
,那么就不要放 -w
参数了,不然运行会报错,毕竟 Hello World!
需要在命令行里打印出来。此外,-w
参数在 GUI 界面时非常有用。
补充:-i
就是指设置自己的图标图案,因为默认打包图片是下图这样的。这个参数也可以写成 --icon=aiyc.ico
最后稍微总结一下:
Pyinstaller -F py_word.py 打包exe
Pyinstaller -F -w py_word.py 不带控制台的打包
Pyinstaller -F -w -i chengzi.ico py_word.py 打包指定exe图标打包
以上三个是比较常用的参数,其他参数详见下表
Pyinstaller 参数大全
ico 图片生成
自己做的软件都喜欢放上自己的图标,不过哪来那么多 ico 图片呢?
一个是可以找专门的 ico 图片网站,不过都很小众,图片库也很小。
另一个是可以自己生成,这里就给大家分享一个网站,可以把其他格式图片转成 ico 格式:https://app.xunjiepdf.com/img2icon/
ico 图片格式转换
压缩打包
好了,小伙伴们
来到了最激动人心的时刻,刚刚生成的 exe 实在太大了,300 多 M 的软件程序想用微信传一下都费劲。
我也试过很多方法,比如:修改 spec 文件自定义打包、pipenv 虚拟环境、使用开源的 upx 压缩等等,但是往往要么过程比较麻烦,要么成功率不高(压缩成不成功全看脸)。
而我要分享的,是自己一直在用的,最简单且成功率极高的方法——conda 创建虚拟环境。
Python 打包为什么大?
在压缩打包之前,先简单说一下为什么 Python 打包过大?
Python 打包 exe,不但体积大而且运行奇慢。解释型语言大都是这个样子,只不过 Python 尤其突出。要解决大而慢,只能用编译型语言,如 C,C++,甚至 VB 都好很多,体积最小的是汇编。
此外,还有知乎大佬说是因为“Anaconda 里内置了很多库,打包的时候打包了很多不必要的模块进去,要用纯净的 Python 来打包。”
所以我们可以模拟一个新环境,其中只安装我们本次打包所必要的工具包即可。
那最适合的就是——虚拟环境了!
虚拟环境
Python 创建虚拟环境的方法有很多,而我是个 Anaconda忠实用户,如果你跟我一样,那就简单了。(大家也可以使用Virtualenv、Pipenv来设置虚拟环境,善用搜索,方法大同小异)
先记几个命令,很简单
conda create -n 虚拟环境名字 python==3.6 #创建虚拟环境
conda activate 虚拟环境名字 #激活虚拟环境
conda deactivate #退出虚拟环境
从开始菜单运行“Anaconda Prompt”,出现的界面输入创建虚拟环境的指令。成功创建了一个名字为aotu
,且基于 python 版本 3.6 的虚拟环境。
在创建过程中需要回复(y/n),Yes,再激活虚拟环境
conda 安装的虚拟环境,会把虚拟环境的目录生成在anaconda安装目录下的env目录下。
当然我们也可以在刚刚的窗口,使用命令conda info --envs
,来查看conda环境下所有的虚拟环境
安装所需的库
上面我们已经创建并激活了名为aotu
虚拟环境,输入conda list
可以查看当前虚拟环境里已经安装的库。
我们打开所要打包的Python脚本,对比上图,发现pandas
,docx
这两个库还需要额外安装。当然,也不能缺了打包必不可少的pyinstaller
库。
待打包脚本
安装库的过程不再赘述
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-docx
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller
安装后再看
已成功安装,还有一些因为这几个库所附带安装的,就不管他们了。
Pyinstaller打包步骤
这里就不再重复了,只换个苹果图标试试
Pyinstaller -F -w -i apple.ico py_word.py
生成
成功压缩到29.8M,如果不导入pandas这位大神,应该就可以10多M了
运行一下,毫无问题
最后再简单总结一下虚拟环境+打包的全过程(只三步):
#创建虚拟环境
conda create -n aotu python=3.6
#激活虚拟环境
conda activate aotu
#Pyinstaller打包
Pyinstaller -F -w -i apple.ico py_word.py
总结一些小坑
1、说起来还是有点玄学,上文中一模一样的过程我在两个电脑都执行过一遍。在其中一个上显示缺少xlrd
这个库,安装后成功打包,也是一样的大小。小伙伴们可以在文末获取文件,也试试。
2、在安装库是要注意一些库名,比如docx这个库不要pip install docx
,而是需要
pip install python-docx
还有一些库可能因为版本不同导致不能使用,多碰碰壁就好了。
3、为了防止打包时候有些库没安装好,可以先在虚拟环境中执行一下Python脚本。运行无误的话再打包,比较保险。
4、最后,如果想要删除虚拟环境的话,可执行下方命令
conda remove -n aotu--all
5、打包为 exe 的话,版本尽量选择python3.6+32位版本,因为win64位系统向下兼容32位程序,但是如果不考虑32位系统的话无所谓,直接python64位版本直接打包就可以,只是只能在win64位系统上跑。[2]