使用PyInstaller打包Python程序并压缩体积
本文介绍如何使用PyInstaller将Python脚本打包为可执行文件,并解决打包后体积过大及依赖缺失的问题。通过结合Pipenv创建纯净虚拟环境,可有效剔除冗余模块,显著减小最终发布包的体积。
PyInstaller打包Python程序及压缩体积指南
近期应导师要求,为实验室开发了一款基于PyQt5的小工具。在提交源码后,对方反馈需要直接提供打包好的可执行软件。
既然需求如此,便尝试使用之前接触过的PyInstaller进行打包。本文主要记录基本使用方法及过程中遇到的常见问题。
使用PyInstaller进行Python程序打包
1. 使用PyInstaller进行Python程序打包
首先需安装PyInstaller工具。
pip install pyinstaller
虽然可以使用conda进行安装,但近期清华Anaconda源似乎处于封闭状态,恢复时间尚不明确。
PyInstaller的操作非常简便,只需在包含主调py文件的目录下执行相关命令即可。
pyinstaller [<args>] Target.py
以下介绍PyInstaller常用参数:--distpath <path>用于指定打包输出目录;-w参数表示生成GUI软件,运行时不显示控制台窗口;-c参数则强制打开控制台;-i <Icon File>用于指定生成的可执行文件图标;--clean参数可在构建前清理PyInstaller缓存及临时文件。
关于打包格式,主要有两种选择:
-D模式:创建包含可执行文件及大量依赖dll文件的单文件夹包,此为默认选项;-F模式:仅生成单个.exe文件。若项目较小可使用此模式,但大型项目不建议使用,因为可能导致文件过大或启动缓慢。
以下是我实际使用的打包参数示例。
pyinstaller --distpath Release/ -w -i x.ico --clean main.py
若未指定--distpath参数,默认输出目录为dis。进入该目录即可看到打包好的软件。

看起来,生成的文件与正规发布的软件无异。
然而,这并不意味着程序一定能正常运行。
处理依赖项问题
2. 处理依赖项问题
当我尝试运行打包后的程序时,遇到了如下报错:

Failed to excute script xxx
出现此错误通常是因为缺少必要的依赖项。以我的项目为例,运行时需读取config.yaml配置文件,但PyInstaller默认不会自动打包此类非Python文件。
解决方法是手动将相关依赖文件复制到打包目录中。
至此,打包工作似乎就完成了——真的吗?
并没有!我遇到了一个令人头疼的问题:打包后的程序体积竟高达600多MB。
经过反复排查,我发现了一些异常之处。

我不记得在项目中引入过Numpy,但打包结果中却包含了它。推测是PyInstaller自动打包了Anaconda环境中内置的大量非必要库。有技术社区指出,使用纯净的Python环境进行打包可以避免此类问题。
为此,我采用了Pipenv来进行打包操作。
使用Pipenv优化打包过程
3. 使用Pipenv优化打包过程
Pipenv是一款用于管理虚拟环境的命令行工具。其核心功能是创建仅存在于特定目录下的局部Python环境,从而与全局环境隔离。
具体操作步骤如下:
首先安装Pipenv。
pip install pipenv
选择一个合适的目录作为虚拟环境的工作目录,并在该目录下执行初始化命令。
pipenv install --python 3.7
这样即可在指定目录下创建局部环境。此处指定Python版本为3.7,可根据实际需求调整版本号。
接下来在命令行中激活该环境。
pipenv shell
执行该命令后,即进入新建的虚拟环境。此时若使用pip list命令,发现已安装的库极少,则说明虚拟环境创建成功(这与Conda的行为类似)。
随后安装所需的依赖库。
在虚拟环境下,安装PyInstaller及脚本所需的第三方库。例如我的项目需要安装:
pipenv install pyinstallerpipenv install pyqt5pipenv install pymysqlpipenv install geopy
再次使用pip list确认所有依赖库均已成功安装后,即可开始打包。
将脚本文件移至该目录,并执行pyinstaller命令,方法与前述相同。
此时,PyInstaller将使用虚拟环境中的库进行打包。由于该环境较为纯净,即使存在其他无关库也不会被打包进去。
打包完成后,可以明显感觉到文件体积显著减小。

最终体积仅为90MB,相比之前的600MB缩小了六倍以上。
以上即为本文的全部内容,希望对各位的学习有所帮助,也欢迎大家继续支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









