你是不是也遇到过这种情况。辛辛苦苦写了一堆Python代码,功能也就那么几十行,打包成exe文件后一看大小,好家伙,100多兆。发给朋友用,人家第一反应是你这什么软件这么大,第二反应是下载太慢算了不装了。
最近我折腾了个小项目,就是那种扫雷游戏,代码量不大,依赖库也没几个。按常规流程用PyInstaller打包,32兆。感觉还行吧,但想想还是太大了。翻了很多资料,折腾了两天,硬是从100兆的项目压缩到了15兆。这话不夸张,我试过的一个综合项目从108兆缩到了14.7兆。
先说最狠的一刀。很多人打包出来大,是因为把整个Python解释器和所有库一股脑全塞进去了。哪怕你只用了某个库里的一个函数,它也会把整个库文件夹搬进来。我用的办法是先用pipenv创建虚拟环境,只装确实用到的库。然后打包时候要用--onefile参数,它会把所有零散文件合成一个独立的exe,但这还不够小。
关键一步是手动清理打包后的目录。PyInstaller生成的有个叫_pyinstaller_hooks_的文件夹,里面好多文件是多余的。像pytz时区数据包,动辄几兆,你要是没用到世界时间,直接删掉。还有numpy库,它自带的测试文件也很大,我直接把numpy的测试文件夹删了。删完重新打包,体积一下就下来了。
另一个常用技巧是用UPX工具压缩。这是个压缩执行文件的工具,能把exe变小30%到50%。下载后把路径配置到PyInstaller的打包命令里就行。我试过,一个40兆的文件压完变成25兆,效果很明显。
如果你愿意再深入一点,可以试试用Nuitka编译。这个工具跟PyInstaller不一样,它不是把Python代码包起来,而是把Python代码转成C++再编译。出来的exe更小,运行速度还快。不过设置起来麻烦点,不是所有人都能一次成功。
说个我踩过的坑。一开始我用Anaconda的环境打包,那体积直接往200兆跑。因为Anaconda自带了一堆科学计算库。后来我换用最小的Python安装包,从官网下的嵌入式版本,才几十兆。然后手动pip只装需要的库,打包出来直接小了一大半。
还有个很多人不知道的地方。你的代码里如果用了print或者logging,打包时候也会把这些功能带进去。如果你只是跑个简单的图形界面,完全可以把这些调试代码去掉。一个print语句对应的模块可能不大,但积少成多啊。
最后给你个清单。先清理代码里的无用import。再用干净的环境打包。加上UPX压缩。手动删掉打包目录里的测试文件和多余数据。最后试试换用更轻量的库,比如用pillow代替opencv处理图片,用sqlite代替pandas处理表格数据。这几步走下来,你会回来感谢我的。