主要问题:
(1)如何同时打包多个python文件
(2)打包过程中有缺失的包怎么处理
(3)如何解决打包程序过大的问题
以上三个问题是使用pyinstaller打包python文件常见的问题,我将以自己开发的一个tkinter程序来进行说明,所有操作与结果自己已经验证。
提示:如果不考虑打包程序大小的问题,可能会出现一个打包的exe程序好几百兆,甚至更大,这不仅占用资源,启动速度也比较慢,所以最好是重新创建一个比较干净的python环境要好一些。
一、创建干净的python运行环境
1、创建一个新的环境
conda create -p PATH -n ENVIRONMENT python=3.10.11
2、安装需要的包
推荐使用pip安装,因为使用conda安装会安装很多其他相关的包,但是考虑到pip下载库很慢,可以在 pip 时加上镜像源的地址:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 需要安装的包的名称
3、在当前环境下安装pyinstaller
以在 pip 时加上镜像源的地址:
pip install installer
结果:经过测试,我自己的打包的exe在原来写代码的环境中创建的包大小接近330M,但是创建一个新的环境之后,我的打包只有70M,虽然还是很大,但是已经能够接受了,启动速度也快了很多,因为我使用的程序里面包括了numpy、pandas、sklearn等几个大包,这几个包单独也是几十M的样子。
二、pyinstaller打包多文件的方法
我的程序需要引用自己的模块,程序结构如下:
主程序只有上面的一个文件,rain和logistics_regression是自己创建的文件夹,下面有python模块,其中在主程序里面引入了如下包:
import tkinter as tk
import tkinter.ttk as ttk
import time
from tkinter.filedialog import askopenfilename,asksaveasfilename
import os
import datetime
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import recall_score # 召回率
from sklearn.metrics import accuracy_score # 精确率
from sklearn.metrics import f1_score # f1# 下面是自己编写的相关包
from rain import rain_extract,rain_solve,date_solve
from logistics_regression import logistics
1 第一步:生成spec文件
(1)首先打开conda prompt
(2)激活自己创建的环境
conda activate python3.10.11
(3) 通过cd命令进入到主程序所在的文件夹
(4)使用pyi-makespec命令生成spec文件
pyi-makespec -F -w tkinter_model.py
# -F 表示将所有的文件打包成一个exe文件
# -w 表示这是一个窗体程序,不需要打开控制台
pyi-makespec命令常见的参数有,还有很多,没列举完全:
> pyi-makespec --help-D, --onedir Create a one-folder bundle containing an executable (default)-F, --onefile Create a one-file bundled executable.-p DIR, --paths DIR A path to search for imports (like using PYTHONPATH). Multiple paths are allowed, separated by';'.--hidden-import MODULENAME, --hiddenimport MODULENAMEName an import not visible in the code of the script(s). This option can be used multipletimes.--exclude-module EXCLUDES Optional module or package (the Python name, not the path name) that will be ignored (asthough it was not found). This option can be used multiple times.Windows and Mac OS X specific options:-c, --console, --nowindowed Open a console window for standard i/o (default). On Windows this option has no effect if thefirst script is a '.pyw' file.-w, --windowed, --noconsoleWindows and Mac OS X: do not provide a console window for standard i/o. On Mac OS this alsotriggers building a Mac OS .app bundle. On Windows this option is automatically set if thefirst script is a '.pyw' file. This option is ignored on *NIX systems.--hide-console {minimize-early,hide-late,minimize-late,hide-early}Windows only: in console-enabled executable, have bootloader automatically hide or minimizethe console window if the program owns the console window (i.e., was not launched from an existing console window).
2 第二步:修改spec文件
spec文件本质上也是一个python文件,只不过后缀改了,格式如下:
# -*- mode: python ; coding: utf-8 -*-a = Analysis(['tkinter_model.py','rain/date_solve.py','rain/rain_extract.py','rain/rain_solve.py','logistics_regression/logistics.py'],pathex=[],binaries=[],datas=[],hiddenimports=["openpyxl.cell._writer"],hookspath=[],hooksconfig={},runtime_hooks=[],excludes=[],noarchive=False,
)
pyz = PYZ(a.pure)exe = EXE(pyz,a.scripts,a.binaries,a.datas,[],name='tkinter_model',debug=False,bootloader_ignore_signals=False,strip=False,upx=True,upx_exclude=[],runtime_tmpdir=None,console=False,disable_windowed_traceback=False,argv_emulation=False,target_arch=None,codesign_identity=None,entitlements_file=None,
)
文件解读:
其中:
(1)表示的是自己写的模块,我全部添加进来了
(2)表示资源数据,比如有一些JSON文件,图片、图标等,放置在当前目录之下的某一个文件夹之下,需要指定,比如 datas=["sources"]
(3)hiddenimports指的是在打包的过程中针对某些缺失的模块隐式导入。比如我的程序如不过不添加这个,在打包完之后运行,会显示一个错误:
No module named 'openpyxl.cell._writer'
所以我需要隐式导入这个模块。
3 第三步:打包,即运行spec文件
Pyinstaller xxx.spec
参考文献:
用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细)_编程网
python程序打包成exe全流程纪实(windows) - 知乎
【python】tkinter程序打包成exe可执行文件 全流程记录(windows系统)
PyInstaller打包exe闪退,No Model named XXX问题_pyinstaller打包 no module named 'openpyxl.cell._writ-CSDN博客