PyInstaller打包体积大是因为默认打包整个Python环境及未引用的依赖。需用--exclude-module剔除无用模块,配合--upx-exclude避免C扩展压缩失败,并通过.spec文件精细控制依赖和资源。

为什么PyInstaller打包后体积大得离谱
PyInstaller默认会把整个Python解释器、标准库、所有依赖包全打包进去,哪怕你只用了json和os两个模块,它也会带上numpy(如果环境里有)、ssl、tkinter甚至distutils——这些根本没被你的代码引用,但PyInstaller静态分析时“不敢删”。更麻烦的是,它还会把C扩展的调试符号、多语言本地化文件、测试用例等一并塞进去。
用--exclude-module精准剔除无用模块
很多项目根本不用GUI、网络服务或数据库,但PyInstaller仍会带入tkinter、urllib3、sqlalchemy等。必须手动排除:
- 常见可排除项:
--exclude-module tkinter、--exclude-module PyQt5、--exclude-module matplotlib、--exclude-module setuptools - 查哪些模块实际被引入:运行
python -c "import sys; print([m for m in sys.modules.keys() if 'urllib' in m or 'ssl' in m])",再结合自己代码确认是否真需要 - 注意顺序:
--exclude-module必须放在pyinstaller命令末尾,否则可能不生效
启用--onefile + --upx-exclude绕过UPX误压缩
UPX能压缩二进制,但对某些C扩展(如_ssl.pyd、_hashlib.pyd)加壳后会导致运行时报ImportError: DLL load failed。不能全局开UPX,得有选择地用:
- 先装UPX:
choco install upx(Windows)或brew install upx(macOS) - 用
--upx-exclude _ssl --upx-exclude _hashlib --upx-exclude pyexpat排除高危模块 -
--onefile本身不减体积,但配合UPX时更易控制压缩粒度;若追求启动速度,改用--onedir反而更稳
用.spec文件精细控制data和hook
自动分析常漏掉动态导入(比如importlib.import_module('plugins.' + name)),导致运行时报ModuleNotFoundError;也容易把整个site-packages当资源拷进去。这时必须改.spec:
- 生成初始spec:
pyinstaller --onefile your_script.py,然后编辑生成的your_script.spec - 在
a = Analysis(...)里删掉pathex中非必要路径,添加excludes=['tests', 'docs', 'examples'] - 在
coll = COLLECT(...)前加a.binaries = a.binaries - TOC([x for x in a.binaries if 'test' in x[0].lower()]),批量剔除测试二进制
体积能不能压到10MB以内,关键不在删多少,而在搞清哪些模块是“被连坐”的——比如装了pandas就必然带numpy,但如果你只用pandas.read_csv,其实可以手动替换为csv模块+open(),彻底绕过整套生态。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











