uv + PyInstaller:Windows 下打包 .exe 步骤与细节
说明 :
uv(Astral)负责 Python 版本、虚拟环境、依赖锁定与运行命令;不直接生成.exe。生成可执行文件需在项目内使用 PyInstaller (或 Nuitka、cx_Freeze 等),通过uv run在统一环境中调用。
一、整体流程
- 用
uv初始化项目、固定 Python 版本、安装依赖 - 将 PyInstaller 加入开发依赖(
--dev) - 使用
uv run pyinstaller或uv run python -m PyInstaller打包 - 按需处理资源文件、隐藏导入、
.spec文件
产物通常在项目下的 dist\ 目录。
二、环境准备
1. 安装 uv
以官方文档为准:Getting started | uv
PowerShell 示例:
powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
2. 初始化项目并固定 Python
powershell
cd D:\path\to\your\project
uv init
# 可选:指定 Python 版本(例如 3.12)
uv python pin 3.12
3. 安装业务依赖与 PyInstaller
powershell
uv add requests
uv add --dev pyinstaller
三、基本打包命令
1. 单文件 exe(最常见)
入口为 main.py 时:
powershell
uv run pyinstaller --onefile --name MyApp main.py
--onefile:输出单个.exe,分发简单;启动时会解压到临时目录,体积略大、冷启动略慢。--name MyApp:生成的 exe 名称(不含.exe后缀)。
输出路径:dist\MyApp.exe。
2. GUI 程序(不显示黑色控制台)
powershell
uv run pyinstaller --onefile --windowed --name MyApp main.py
-w 与 --windowed 等价。
3. 指定图标
powershell
uv run pyinstaller --onefile --icon=assets\app.ico --name MyApp main.py
4. 若直接调用 pyinstaller 异常(Windows 偶发)
改用模块方式,避免脚本包装问题:
powershell
uv run python -m PyInstaller --onefile --name MyApp main.py
四、重要细节
1. 资源文件(--add-data)
Windows 下 PyInstaller 的 --add-data 格式为 源路径;目标路径(分号分隔)。
示例:将项目下的 config 目录打进包,运行时解压到名为 config 的目录:
powershell
uv run python -m PyInstaller --onefile `
--add-data "config;config" `
--name MyApp main.py
建议在代码中用 importlib.resources 或基于 sys._MEIPASS 的路径解析资源,避免写死开发机绝对路径。
2. 隐藏导入(ModuleNotFoundError)
动态导入或 C 扩展依赖未被打包分析到时,需显式声明:
text
--hidden-import=包名或模块名
可重复多次。
3. 使用 .spec 文件(推荐复杂项目)
首次生成 spec:
powershell
uv run python -m PyInstaller --name MyApp main.py
编辑生成的 MyApp.spec ,调整 Analysis 中的 datas、hiddenimports,再执行:
powershell
uv run python -m PyInstaller MyApp.spec
4. 多文件目录模式(启动更快)
不使用 --onefile 时,默认输出目录 dist\MyApp\ ,内含 MyApp.exe 及依赖文件,需整目录一起分发。
powershell
uv run python -m PyInstaller --name MyApp main.py
5. 可复现构建(uv.lock)
- 将
pyproject.toml与uv.lock纳入版本控制。 - 新机器执行
uv sync后,依赖与本地一致,再执行相同 PyInstaller 命令即可复现构建。
6. 架构与运行库
- 打包机与目标用户尽量同为 x64(或同为 ARM64)。
- 若依赖 C 扩展,注意目标机是否安装 VC++ 可再发行组件(视依赖而定)。
7. 杀毒误报与签名
- 单文件 exe 易被启发式拦截,属常见现象。
- 企业内分发可考虑 代码签名 降低误报。
五、uv build 与 exe 的区别
| 命令 | 产物 | 用途 |
|---|---|---|
uv build |
wheel / sdist | 发布到 PyPI 或内网制品库 |
| PyInstaller 等 | .exe + 可能附带目录 |
终端用户免装 Python 直接运行 |
uv build 不会生成独立 .exe。
六、备选打包工具(简要)
| 工具 | 特点 |
|---|---|
| PyInstaller | 使用最广,文档与社区多;上文默认方案 |
| Nuitka | 编译为 C 再链接,体积与保护性可能更好,构建更长 |
| cx_Freeze | 跨平台打包,配置方式与 PyInstaller 不同 |
同样可在 uv 环境中:uv add --dev nuitka 后 uv run python -m nuitka ...(具体参数见各工具文档)。
七、参考链接
- uv 文档:https://docs.astral.sh/uv/
- PyInstaller 手册:https://pyinstaller.org/