Python打包教程
最近使用python开发了一个windows桌面应用,本篇博客就用来总结python打包的相关知识,同时简说开发。本文将记录笔者使用pyinstaller踩的所有坑。
一、环境准备(开发)
如果你已经开发完了只想打包,可以跳过此步骤。
开发一个项目通常需要使用到虚拟环境,这是为了防止在开发过程中面临环境冲突、环境污染的情况。
这里使用conda来创建虚拟环境。conda下载
conda有conda和miniconda,两者功能一样,但miniconda更小,速度更快。这里笔者使用的是miniconda。
1 | $ conda env list # 查看所有虚拟环境 |
第一次使用conda来激活虚拟环境会遇到很多问题,如在初始化shell环境时会遇到:
1 | . : 无法加载文件 D:\win11\Documents\WindowsPowerShell\profile.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 htt |
这是 PowerShell 执行策略(Execution Policy)阻止了脚本运行,导致 conda 的初始化脚本 profile.ps1
无法加载。
✅ 解决方法(只需执行一次):
1. 打开 PowerShell(管理员模式)
- Win + X → 选择 “Windows PowerShell(管理员)”
2. 运行以下命令,允许当前用户运行本地脚本:
1 | Set-ExecutionPolicy -Scope CurrentUser RemoteSigned |
3. 按提示输入 Y
或 A
确认即可。
✅ 完成后:
关闭 PowerShell,重新打开一个 普通 PowerShell 窗口(非管理员),然后运行:1
conda activate 你的环境名
应该就能正常使用了。
🔍 补充说明:
RemoteSigned
是较安全的策略,允许运行本地脚本,但远程下载的脚本需要签名。- 如果你不想改策略,也可以每次手动运行:但这不是推荐方式。
1
& 'D:\win11\Documents\WindowsPowerShell\profile.ps1'
虚拟环境激活后,整个项目就在这个环境中开发(这很重要,开发过程中要时刻清除你到底是用的哪个环境来开发的,环境弄错了后面可能会产生麻烦的后果)。
二、安装pyinstaller
然后是安装pyinstaller,这是python的打包工具,用来将python项目打包成exe文件。
1 | $ conda activate your_envs # 激活虚拟环境 |
如果不是虚拟环境,自行省略虚拟环境的部分,包括后面的。
或者使用离线安装,安装方式:
在 Pyinstaller离线包链接 中选择最新版win64位的下载即可,然后安装方式同上:先激活你的虚拟环境,然后 pip install
把你刚下载好的离线文件拖到这个pip install 后面回车即可。
三、Pyinstaller 生成exe(程序无传参版)
Pyinstaller的语法在Windows,MacOS和Ubuntu的语法相同,但是在Windows下打包的应用只能在Windows下使用,MacOS和Ubuntu同理。
简易版
首先我们有一个写好的脚本test.py
,然后打包指令为
1 | $ pyinstaller -F test.py |
会在你的python根下生成一个 build 和 dist 文件夹还有一个 spec 文件,你生成的exe就在dist
里边。双击即可运行。
进阶版
下面来看一下pyinstaller的参数
参数 | 说明 |
---|---|
-h | 该模块的help信息 |
-F | 生成一个可执行文件 |
-D | 生成一个目录(包含多个文件)作为可执行文件 |
-w | 运行exe时,不显示命令行窗口(仅对Windows有效) |
-i | 该参数后跟可执行文件的icon图标路径 |
—distpath | 该参数后跟可执行文件的路径 |
-n | 该参数后跟可执行文件的新名字 |
详细参数说明请查看:PyInstaller 中文文档
笔者这次开发用的生成指令:
1 | $ pyinstaller --onedir --contents-directory . -w ^ |
参数解释:
| 参数 | 说明 |
| —— | —— |
| --onedir
| 生成包含所有依赖的文件夹(默认打包方式,与-D
等效) |
| --contents-directory .
| 输出格式保留源文件结构(Pyinstaller>=6.0.0) |
| -w
| 创建Windows窗口化程序(不显示控制台,GUI模式) |
| --add-data "resources;resources"
| 添加资源文件夹(格式为”源路径;目标路径”,Windows使用分号分隔) |
| --hidden-import=PyQt5.sip
| 显式包含PyQt5的sip模块(自动检测可能遗漏的依赖) |
| -i logo.ico
| 设置应用程序图标(需提前准备.ico格式文件) |
| --add-data "mathjax;mathjax"
| 添加数学公式渲染所需的MathJax库 |
| --version-file file_version_info.txt
| 注入Windows可执行文件版本信息(需单独编写版本文件) |
| --name Cheqory
| 指定生成的可执行文件名称(默认与主脚本同名) |
| main_control.py
| 应用程序入口文件(主程序脚本) |
四、Pyinstaller 生成exe(程序带参数版)
相信写好的脚本都有 输入 和 输出,那么现在分两种方法进行介绍:
相对路径传参
首先在python脚本中获取当前文件路径,然后倒推同根下或者上一级文件,前提是首先把你的输入路径写死,比如
1 | project |
那么你的python就可以通过 os.getcwd()
获取project的路径,然后向子路径寻找你的input;或者通过 os.path.dirname(os.path.abspath(__file__))
来获取project的路径,然后告诉你的小姐姐说:你的文件都要放在这个input下才行~
然后:
1 | $ pyinstaller -F test.py |
指定路径传参
指定路径通过sys.argv[]
来传递test.py
的参数,如下
1 | # test.py |
在终端运行时使用 python test.py 1 2
即可。
然后:
1 | $ pyinstaller -F test.py |
继续:
1 | $ cd 你的test.exe路径下 |
这样即可通过指定参数完成传递。
五、Pyinstaller打包多个py文件为一个exe文件
打包的文件可能包含多个py脚本和一些其他类型文件,如xml, ui, pth等等。因为需要调用的文件较多, 建议将所有的非py脚本放在根目录下新建文件夹中去调用,所有的py脚本放在根目录下,这样看起来会十分的整洁,笔者亲身经历。前提要保证放在文件夹中的非py文件可以正确被调用哦。直接上栗子🌰:
你的目录长这个样子:
1 | project |
你需要这样运行即可:
1 | $ cd project |
如果想给exe添加icon,可以第三节中进阶版中的参数,是一样的。
六、踩坑和遇到的问题
- 程序要严谨,在程序内部使用相对路径,main主函数中的接口可以通过argv外传参数;也可以使用相对路径。建议使用第二种,简便。
- exe文件是可以直接拖入激活虚拟环境的cmd中进行debug的。
- 如果是使用虚拟环境开发,pyinstaller打包用的是虚拟环境的pyinstaller,不要随便一个目录打开终端就运行pyinstaller打包,一定要在项目目录下打开终端使用虚拟环境的pyinstaller进行打包,要不然第三方库的引用会出错。
- ico图标可以通过度娘 ico生成器 进行生成
- 被调用的脚本需要拷贝到dist中打包好的文件夹中,否则可能导致调用失败
- 运行exe后如果提示缺少文件,就去anaconda下搜索缺少的依赖文件,复制到exe同根下即可(其实很有可能你没成功使用开发环境的pyinstaller,要注意尤其是用了虚拟环境的)。