📦 PyInstaller 打包说明(中文指南)
下面按 准备 → 基本使用 → 常用参数 → 进阶技巧 → 常见问题 的顺序,系统地介绍如何使用 PyInstaller 将 Python 程序打包成可执行文件(.exe / 可执行二进制)。
1️⃣ 环境准备
| 步骤 |
操作 |
| ① 安装 Python |
建议使用 3.8‑3.11(官方已兼容),并把 python、pip 加入系统 PATH。 |
| ② 创建虚拟环境(可选) |
bash\npython -m venv venv\nsource venv/bin/activate# Linux/macOS\nvenv\Scripts\activate# Windows\n |
| ③ 安装 PyInstaller |
bash\npip install --upgrade pyinstaller\n |
| ④ 检查依赖 |
确认项目可以在当前环境正常运行(python main.py),避免遗漏第三方库。 |
2️⃣ 基本使用
2.1 单文件(One‑File)模式
1
|
pyinstaller -F your_script.py
|
-F / --onefile:把所有依赖压缩进一个 .exe(启动时会临时解压到 %TEMP%)。
- 生成目录结构(默认在当前工作目录):
1
2
3
4
|
your_script.spec
build/# 编译中间文件,可删除
dist/
your_script.exe# 目标可执行文件
|
2.2 多文件(One‑Dir)模式(默认)
1
|
pyinstaller your_script.py
|
- 生成
dist/your_script/ 目录,里面包含 exe、DLL、Python 库等,便于调试。
2.3 常用快捷方式
1
|
pyinstaller -c your_script.py# -c == --console
|
- 添加图标(Windows
.ico、macOS .icns)
1
|
pyinstaller -F -i app.ico your_script.py
|
3️⃣ 常用参数一览(推荐组合)
| 参数 |
说明 |
示例 |
-F / --onefile |
单文件输出 |
pyinstaller -F main.py |
-D / --onedir |
目录输出(默认) |
pyinstaller -D main.py |
-n NAME |
自定义生成文件名 |
pyinstaller -n MyApp main.py |
-i ICON |
添加图标 |
pyinstaller -i logo.ico main.py |
-c / --console |
控制台模式(显示日志) |
pyinstaller -c main.py |
-w / --windowed |
窗口模式(无控制台) |
pyinstaller -w main.py |
--add-data SRC;DEST |
打包额外数据文件(Windows 用 ;,Linux/macOS 用 :) |
pyinstaller --add-data "config.yaml;." main.py |
--add-binary SRC;DEST |
打包二进制文件(DLL、so) |
pyinstaller --add-binary "libfoo.dll;." main.py |
--hidden-import MOD |
手动声明隐式导入的模块 |
pyinstaller --hidden-import=pkg.module main.py |
--exclude-module MOD |
排除不需要的模块,减小体积 |
pyinstaller --exclude-module=tkinter main.py |
--collect-all PKG |
收集整个包(包括子模块、数据) |
pyinstaller --collect-all=opencv-python main.py |
--clean |
打包前清理旧的 build/、dist/ |
pyinstaller --clean main.py |
--debug=all |
输出调试信息,帮助定位错误 |
pyinstaller --debug=all main.py |
--noupx |
禁用 UPX 压缩(有时兼容性更好) |
pyinstaller --noupx main.py |
--upx-dir DIR |
指定 UPX 所在目录 |
pyinstaller --upx-dir=C:\upx main.py |
--specpath DIR |
.spec 文件保存路径 |
pyinstaller --specpath=specs main.py |
--distpath DIR |
可执行文件输出目录 |
pyinstaller --distpath=output main.py |
--workpath DIR |
临时工作目录 |
pyinstaller --workpath=tmp main.py |
4️⃣ 进阶技巧
4.1 使用 .spec 文件自定义
第一次运行 pyinstaller your_script.py 会生成 your_script.spec。可以手动编辑后再次打包:
1
|
pyinstaller your_script.spec
|
常见编辑点:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
a = Analysis(
['your_script.py'],
pathex=['.'],
binaries=[],
datas=[
('data/config.yaml', 'data'),# 把 data 目录打进去
('resources/', 'resources')# 整个文件夹
],
hiddenimports=['pkg.module'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
)
|
4.2 兼容临时解压路径(单文件模式)
打包后运行时,资源文件会被解压到 sys._MEIPASS。如果代码中需要读取本地文件,推荐使用:
1
2
3
4
5
6
|
import sys, os
def resource_path(relative):
"""在普通运行和 PyInstaller 打包后都能得到正确路径"""
base = getattr(sys, '_MEIPASS', os.path.abspath('.'))
return os.path.join(base, relative)
|
4.3 多平台打包
- Windows → Linux:需要在对应系统下重新执行
pyinstaller(交叉编译不支持)。
- macOS:使用
--windowed 生成 .app,或 -F 生成单文件可执行。
- Linux:常用
--onefile + --add-data,并确保目标机器有相同的 glibc 版本。
4.4 打包 GUI 框架
| 框架 |
关键点 |
| Tkinter |
通常不需要额外操作,只要 --add-data 把图片等资源加入即可。 |
| PyQt5 / PySide2 |
加入 Qt5 相关 DLL:--collect-all PyQt5 或 --add-binary "C:\Python\Lib\site-packages\PyQt5\Qt\bin\*.dll;Qt5/bin"。 |
| wxPython |
同样使用 --collect-all wxPython。 |
| Kivy |
需要 --hidden-import=kivy.deps.sdl2、--hidden-import=kivy.deps.glew 等,或使用官方提供的 kivy_deps 包。 |
5️⃣ 常见问题 & 排查思路
| 现象 |
可能原因 |
排查/解决办法 |
| 运行后立即退出、没有任何提示 |
使用 -w(无控制台)且代码抛异常 |
改为 -c 或加 --debug=all,在终端查看 traceback。 |
ImportError: cannot import name xxx |
隐式导入未被检测 |
在命令行加 --hidden-import=module,或在 .spec 的 hiddenimports 中声明。 |
| 缺少资源文件(图片、模板) |
--add-data 未加入或路径写错 |
确认源路径正确,Windows 用 ; 分隔,Linux/macOS 用 :。重新执行 pyinstaller --clean …。 |
DLL load failed |
动态链接库未打进 |
用 --add-binary 手动加入,或使用 --collect-all=package。 |
| 打包体积异常大 |
把整个 site‑packages 都打进 |
只加入必要的 static、templates,其余交给 PyInstaller 自动收集。 |
在 Windows 7/8 运行报错 The application was unable to start correctly |
缺少 Visual C++ 运行时 |
安装对应的 Microsoft Visual C++ Redistributable,或把 vcruntime140.dll 用 --add-binary 打进去。 |
Linux 上提示 GLIBC_2.28 not found |
目标机器 glibc 版本低于编译机器 |
在相同或更旧的 Linux 环境中重新打包,或使用容器(Docker)构建。 |
快速定位缺失文件:
1
2
3
4
|
# Windows PowerShell
Get-ChildItem -Recurse -Filter "xxx.dll"
# Linux/macOS
find . -name "xxx.so"
|
6️⃣ 打包完整示例(以 Tkinter 程序为例)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 1️⃣ 创建虚拟环境并安装依赖
python -m venv venv
venv\Scripts\activate
pip install pillow# 示例依赖
pip install pyinstaller
# 2️⃣ 编写 main.py(假设使用了 data/config.yaml、images/logo.png)
# 3️⃣ 打包命令
pyinstaller -F -w \
--icon=logo.ico \
--add-data "data/config.yaml;data" \
--add-data "images/logo.png;images" \
--hidden-import=pkg_resources \
--collect-all=pillow \
main.py
|
- 打包完成后,
dist/main.exe 即可直接双击运行,所有资源已内嵌。
📌 小结
- 准备好环境 → 安装
pyinstaller。
- 基本命令:
pyinstaller -F your_script.py(单文件)或 pyinstaller your_script.py(目录)。
- 常用参数:图标、数据文件、隐藏导入、排除模块、调试。
- 进阶:编辑
.spec、兼容 sys._MEIPASS、不同 GUI 框架的特殊处理。
- 排错:先打开控制台模式查看错误信息,再根据报错添加
--hidden-import、--add-data 等。
如果你已经有具体的项目(比如使用了 nicegui、PyQt5、或需要打包成单文件并放到特定目录),可以把项目结构或关键依赖告诉我,我可以帮你写出最合适的 PyInstaller 命令或 .spec 配置示例。 😊