pyinstaller最小化打包py脚本为可执行exe

今天帮同学打包py脚本为可执行程序exe时遇到了文件过大的问题(基于conda环境&pyinstaller),网上查了一下但是很多方案都没说明问题,在此记录一下简要方案以及个人案例。

包安装

1
2
3
pip install pyinstaller
# or upgrade to a newer version:
pip install --upgrade pyinstaller

py打包为exe可以干嘛?不需要安装Python软件环境即可执行程序完成响应的处理,便于共享和处理

步骤及案例参考

原因:如果直接使用conda环境进行打包会出现文件过大的问题,通常是因为基于conda安装的包会比正常pip安装的包更大,打包时会增加依赖,导致最终的exe很大,如只要是包含numpy或者pandas模块的py脚本打包,基本都会大于200M,测试过程略(可以自行新建环境测试包依赖),因此建议是新建环境安装包并打包。这里我一开始直接打包是300M,新环境中打包后为29M,而且由于生成的文件小了,速度也快了很多

新建环境并安装

更多包和环境管理可见Python环境管理,打开命令行依次执行,包通过pip命令安装,版本根据代码执行路径确定

1
2
3
4
5
conda create -n exe python=3.8
conda activate exe
pip install --upgrade pyinstaller
pip install pandas
# 安装pandas会直接安装numpy及其依赖,如果有其他包也直接pip安装

打包

打包会在目录下默认生成临时文件夹Building及包含exe的dist文件夹,可以添加参数指定位置,或生成后删除即可。参数解释

  • -F 指定生成单个exe程序
  • --distpath后跟的是exe文件存放路径,可以使用相对或绝对路径,正反斜杠都可以
  • --workpath后跟的是中间过程文件路径,可以使用相对或绝对路径
1
2
3
4
5
6
7
8
# 进入指定要打包的脚本文件夹
cd C:\Users\huangs\Desktop\test
pyinstaller -F myscript.py
# 相对路径,./代表当期路径下
pyinstaller -F zxzdm.py --distpath ./res --workpath ./res
pyinstaller -F zxzdm.py --distpath .\res --workpath .\res
# 绝对路径
pyinstaller -F myscript.py --distpath C:\Users\huangs\Desktop\test\res --workpath C:\Users\huangs\Desktop\test\res

案例

举例一下应用的场景

比如我有一个任务,每周下载数据并将其按天和城市提取为csv,下载的文件为多个zip压缩文件,压缩文件中为原始的txt,我需要定期多次下载数据并转换。也可以给他人共享

  • 每次都要打开脚本运行会有点心烦,但是又必须经常检查是否下载缺失,于是就可以将脚本转换为exe,将下载的压缩包统统丢进一个文件夹,然后双击exe自动提取和去重文件并转换为按天分割的csv。

写好脚本后进行以下改动,需要注意一下路径问题即可,将所有的绝对路径改成相对路径,涉及文件输出可以新建文件夹mkdir,涉及路径则使用os.path.join拼接,更多文件/文件夹操作可参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 判断文件夹是否存在并新建的函数
def create_dir(cwd):
isExists = os.path.exists(cwd)
if not isExists:
os.makedirs(cwd)
return cwd
# 这里默认获取当前路径,即将exe放在指定文件夹下即可执行
root = os.getcwd()
# process
...
# output
outfounder = os.path.join(root, 'tables')
outfounder = create_dir(outfounder)
...
for i in range(len(outcsvs)):
print(names[i])
path = os.path.join(outfounder,names[i])
outcsvs[i].to_csv(path, index=False)

如果是需要手动指定路径:

1
root=input('请输入data_zip路径:  ')