花了三天写好的 Python 脚本,发给同事说"你直接运行吧",同事回:我没装 Python……
这篇文章,帮你彻底解决这个问题。
📌 先搞清楚原理
Python 是解释型语言,默认必须有 Python 环境才能运行。打包的本质,是把以下三件东西捆绑进一个文件夹或单个 .exe:
① Python 解释器本身(或其核心部分)② 你写的 .py 代码(编译成 .pyc 字节码)③ 所有依赖的第三方库(requests、pandas 等)
打包工具负责把它们组装好,收件人拿到 .exe 直接双击,背后其实是一个"微型 Python 运行时"在默默跑。
两个常见误区
- ❌ 打包后代码完全保密(能反编译,只是增加了门槛)
🪟 Windows 上怎么打包
Windows 上打包工具最成熟,主流选择有三个:
方案一:PyInstaller(最常用 ⭐⭐⭐⭐⭐)
安装
pip install pyinstaller
基础打包命令
# 打包成单个文件夹pyinstaller 你的脚本.py# 打包成单个 .exe 文件(最常用)pyinstaller --onefile 你的脚本.py# 打包时隐藏控制台窗口(GUI程序必加)pyinstaller --onefile --windowed 你的脚本.py# 自定义图标pyinstaller --onefile --windowed --icon=icon.ico 你的脚本.py
常用参数速查表
| |
|---|
--onefile | |
--windowed | |
--icon=xxx.ico | |
--name=程序名 | |
--add-data "文件;目标路径" | |
--hidden-import=模块名 | |
--clean | |
打包成功后,dist/ 目录下会出现你的 .exe 文件。
常见问题处理
▌ 问题①:打包成功,双击闪退 原因:程序本身有错误,或缺少依赖文件 解法:先去掉 --windowed,让控制台显示报错信息
▌ 问题②:提示找不到某个模块 原因:PyInstaller 的静态分析没检测到动态导入 解法:加参数 --hidden-import=模块名
▌ 问题③:打包了图片/配置文件但运行时找不到 原因:--onefile 模式运行时解压到临时目录,路径变了 解法:代码里用以下方式获取资源路径:
import sysimport osdefresource_path(relative_path):"""兼容 PyInstaller 打包后的路径"""if hasattr(sys, '_MEIPASS'): base_path = sys._MEIPASS # 打包后临时解压目录else: base_path = os.path.abspath(".")return os.path.join(base_path, relative_path)# 使用示例img_path = resource_path("images/logo.png")
方案二:cx_Freeze(适合需要更多控制的场景 ⭐⭐⭐)
安装
pip install cx_Freeze
需要写一个 setup.py 配置文件
from cx_Freeze import setup, Executablesetup( name="MyApp", version="1.0", description="我的应用", executables=[ Executable("main.py", base="Win32GUI", # GUI程序用 Win32GUI,命令行用 None icon="icon.ico", target_name="MyApp.exe" ) ])
执行打包
python setup.py build
▌ 优势:生成的是文件夹而非单文件,更新方便,启动速度更快
方案三:Nuitka(性能最好,编译成真正的 C 代码 ⭐⭐⭐⭐)
安装
pip install nuitka
打包命令
python -m nuitka --onefile --windows-disable-console --windows-icon-from-ico=icon.ico 你的脚本.py
▌ 优势:不是打包 Python 解释器,而是把 Python 编译成 C 再编译成机器码,运行速度快 2-5 倍,逆向难度更高 ▌ 劣势:编译慢,需要安装 MSVC(Visual Studio 编译工具),首次配置复杂
Windows 三种方案对比
🐧 Linux 上怎么打包
Linux 上的打包逻辑和 Windows 类似,但目标不是 .exe,而是可执行的二进制文件或 AppImage / DEB / RPM 包。
方案一:PyInstaller(同样适用于 Linux ⭐⭐⭐⭐⭐)
安装
pip install pyinstaller
打包命令(和 Windows 几乎一样)
# 打包为单个可执行文件pyinstaller --onefile 你的脚本.py# 打包后在 dist/ 目录生成可执行文件chmod +x dist/你的脚本 # 赋予执行权限./dist/你的脚本 # 运行
⚠️ 重要提示:Linux 打出来的包只能在 Linux 上运行,Windows 打出来的只能在 Windows 运行,PyInstaller 不支持跨平台打包。
方案二:打包为 AppImage(免安装、跨发行版 ⭐⭐⭐⭐)
AppImage 是 Linux 上的"单文件绿色包",在 Ubuntu、CentOS、Fedora、Arch 上都能直接双击运行。
步骤一:先用 PyInstaller 生成文件夹形式
pyinstaller --onedir 你的脚本.py
步骤二:安装 appimage-builder
pip install appimage-builder
步骤三:生成配置并打包
appimage-builder --generate # 自动检测生成 AppImageBuilder.ymlappimage-builder --recipe AppImageBuilder.yml # 打包
生成 .AppImage 文件后,赋权即可运行:
chmod +x MyApp-x86_64.AppImage./MyApp-x86_64.AppImage
方案三:用 Docker 实现跨平台打包 ⭐⭐⭐
在 Mac/Linux 环境下,用 Docker 模拟 Windows 环境来打出 .exe:
# 拉取打包镜像docker pull cdrx/pyinstaller-windows# 在 Docker 里运行 PyInstaller,打包 Windows exedocker run --rm -v "$(pwd):/src/" cdrx/pyinstaller-windows \"pyinstaller --onefile --windowed main.py"
打包完成后,dist/windows/ 目录下就是 Windows 可用的 .exe 文件。
▌ 优势:不用装 Windows,在 Mac/Linux 上直接打出 Windows exe ▌ 劣势:Docker 镜像较大,首次拉取需要时间
方案四:Nuitka 在 Linux 上编译 ⭐⭐⭐
# 安装依赖sudo apt-get install gcc python3-dev # Ubuntu/Debianpip install nuitka# 编译打包python -m nuitka --onefile 你的脚本.py
Linux 平台打包方式汇总
💡 打包前的最佳实践
① 先生成 requirements.txt,锁定依赖版本
pip freeze > requirements.txt
② 建议在虚拟环境里打包,避免把系统所有库都打进去
python -m venv venvvenv\Scripts\activate # Windowssource venv/bin/activate # Linux/Macpip install -r requirements.txtpyinstaller --onefile main.py
③ 加一个 .spec 文件做精细控制
PyInstaller 第一次打包会生成 程序名.spec 文件,之后直接用:
pyinstaller main.spec # 复用配置,不用每次重写命令行参数
④ 杀毒软件可能误报
打包出的 .exe 包含自解压逻辑,部分杀毒软件会误判。 解决方案:代码签名(购买 EV 证书)或提交到杀毒厂商白名单。
🗂️ 完整工作流程图
写好 .py 代码 ↓建虚拟环境 + 安装依赖 ↓测试代码无误 ↓选择打包工具 ↓首次打包(生成 .spec) ↓处理路径/缺依赖/闪退问题 ↓用 .spec 稳定复现打包 ↓测试 .exe 在干净机器上运行 ↓分发给用户
🔖 场景速查
| |
|---|
| |
| |
| |
| |
| 在 Linux/Mac 打 Windows exe | Docker + pyinstaller-windows |
| |
写在最后
打包不是终点,而是让工具真正用起来的最后一步。
Python 写的东西,不应该只活在开发者的电脑上。会写代码,再会打包,才是一个完整的自动化闭环。
下次写完脚本,顺手打个包,同事就不用再问"我没装 Python 怎么办"了。
工具速记:Windows 日常首选 PyInstaller / 性能要求用 Nuitka / Linux 分发用 AppImage / 跨平台打包用 Docker