✅ 适用场景
- 你有一个基于 Python 编写的程序,希望将其打包为 独立可执行文件,方便部署和分发
- 目标环境为 Ubuntu 或类 Unix 系统
- 避免目标环境需要安装 Python 和依赖库
🧱 一、环境准备
1. 安装 Python 和 pip
确保系统中已经安装 Python 3:
sudo apt update
sudo apt install -y python3 python3-pip
如果你使用的是 Python 源码安装(如 3.12+),确保路径正确,建议使用虚拟环境隔离:
python3 -m venv venv
source venv/bin/activate
2. 安装 PyInstaller
pip install pyinstaller
你可以验证是否安装成功:
pyinstaller --version
🛠 二、编写一个简单的 Python 应用
假设你有一个名为 app.py 的程序如下:
# app.py
import time
def main():
print("程序正在运行...")
time.sleep(3)
print("任务完成")
if __name__ == "__main__":
main()
📦 三、使用 PyInstaller 打包
执行打包命令:
pyinstaller --onefile app.py
常见参数解释:
| 参数 | 含义 |
|---|---|
--onefile | 打包成单个可执行文件 |
--noconsole | (GUI 程序使用)打包后不显示控制台 |
--name=xxx | 指定输出程序名 |
--add-data | 添加资源文件(格式:路径:目标路径) |
💡 示例:打包带资源文件
pyinstaller --onefile --add-data "config.yaml:." app.py
表示将本地的 config.yaml 打包到程序中当前目录。
📁 四、打包结果说明
执行完后目录结构如下:
dist/
└── app # ← 打包后的可执行文件(单个文件)
build/
└── ... # 临时构建文件,可删除
app.spec # 打包配置文件(可修改后重复打包)
最终的 dist/app 就是你可以分发和运行的独立程序:
./dist/app
🧱 五、常见问题解决
1. 缺少依赖、导入失败
- 某些模块如
cv2,dlib,numpy使用了 C 扩展,打包时需手动包含 - 可使用
--hidden-import=xxx参数添加缺失模块
pyinstaller --onefile app.py --hidden-import=cv2
2. 字体/图片/配置文件无法访问
使用 --add-data 明确打包:
pyinstaller --onefile --add-data="assets/logo.png:assets" app.py
并在代码中通过运行时目录获取:
import sys
import os
def resource_path(relative_path):
# 兼容 PyInstaller 的路径获取方式
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
3. 文件太大怎么办?
- 使用
--onefile会导致体积变大(包含 Python 解释器) - 若可接受多个文件形式,可以移除
--onefile,体积会小很多 - 可用 UPX 压缩:
sudo apt install upx
pyinstaller --onefile --upx-dir=/usr/bin upx app.py
🧪 六、验证部署环境
可以将 dist/app 拷贝到无 Python 的目标机器运行:
scp dist/app user@remote:/home/user/
ssh user@remote
./app
确保依赖的库、字体等都已包含。
📌 小结
| 步骤 | 说明 |
|---|---|
| 安装 | pip install pyinstaller |
| 打包 | pyinstaller --onefile app.py |
| 添加资源 | --add-data="file:dir" |
| 兼容路径 | 使用 sys._MEIPASS 方式 |
| 减小体积 | 使用 UPX 压缩 |