Pyinstaller实现python程序打包实际案例
2022-05-12 本文已影响0人
陈天睡懒觉
参考网址:https://zhuanlan.zhihu.com/p/370914926
- 用anaconda的conda命令创建虚拟环境,因为打包时会把当前环境下的所有包都打包,生成的文件还会很大,所以创建虚拟环境,只装用到的包
- 激活虚拟环境,在虚拟环境中安装所需要的包和pyinstaller包
- 准备好打包的文件,包含图标.ico文件,python程序和所需的其他文件,放在一个文件夹内
- 用Pyinstaller命令打包
- 删除虚拟环境
虚拟环境准备
conda create -n tempenv python==3.6 #创建名为tempenv的虚拟环境,并在环境中安装指定版本的python
conda activate tempenv #激活虚拟环境
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller #安装需要的包
conda list #查看虚拟环境所安装的包
conda deactivate #退出虚拟环境
conda info --envs #查看所有的环境
检查代码并打包
PMI文件夹:
- pmi.ico
- PMI.py
conda activate tempenv #激活虚拟环境
cd xxxxx #切到当前目录
python xxx.py #检查程序运行是否正常
Pyinstaller -D -i pmi.ico PMI.py
打包完成后,PMI文件夹会生成:
- build文件夹
- dist文件夹
- PMI.spce
dist文件夹中的PMI文件夹里有PMI.exe
conda remove -n tempenv --all #删除虚拟环境
备注:图标文件必须是16×16的,不然会报错。用格式工厂转化成ico 文件即可。
实际案例
打包预测程序,需要用到XGBOOST,并读取一个训练好的XGBOOST模型(XGB.pkl)用于预测
Pyinstaller -D -i kabisou.ico predict.py
打包过程顺利,没有出错,但是运行predict.exe出错,如下:
Traceback (most recent call last):
File "predict.py", line 2, in <module>
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "PyInstaller\loader\pyimod03_importers.py", line 495, in exec_module
File "xgboost\__init__.py", line 9, in <module>
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "PyInstaller\loader\pyimod03_importers.py", line 495, in exec_module
File "xgboost\core.py", line 203, in <module>
File "xgboost\core.py", line 157, in _load_lib
File "xgboost\libpath.py", line 64, in find_lib_path
xgboost.libpath.XGBoostLibraryNotFound: Cannot find XGBoost Library in the candidate path. List of candidates:
- C:\Users\861xx\Desktop\match\dist\predict\xgboost\lib\xgboost.dll
- C:\Users\861xx\Desktop\match\dist\predict\xgboost\..\..\lib\xgboost.dll
- C:\Users\861xx\Desktop\match\dist\predict\lib\xgboost.dll
-C:\Users\861xx\Desktop\match\dist\predict\xgboost\../../windows/x64/Release/xgboost.dll
- C:\Users\861xx\Desktop\match\dist\predict\xgboost\./windows/x64/Release/xgboost.dll
XGBoost Python package path: C:\Users\861xx\Desktop\match\dist\predict\xgboost
sys.prefix: C:\Users\861xx\Desktop\match\dist\predict
See: https://xgboost.readthedocs.io/en/latest/build.html for installing XGBoost.
[21320] Failed to execute script 'predict' due to unhandled exception!
predict.py 第二行代码是 import xgboost,说明xgboost导入失败,需要修改predict.spec文件,加上xgboost包的路径如下:
(没用base环境的路径,我用的虚拟环境的路径,可以尝试用base环境的路径)
a = Analysis(['predict.py'],
pathex=[],
binaries=[],
datas=[('D:\ProgramData\Anaconda3\envs\tempenv\Lib\site-packages','.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
运行 pyinstaller -F predict.spec 出错,错误如下:
Unable to find "D:\ProgramData\Anaconda3\envs empenv\Lib\site-packages" when adding binary and data files.
修改路径文件路径如下:
(看到过将Lib改成lib的方法,无效,换成双斜杠后就行了,很奇怪报错中没有完整显示路径,具体原因不明)
datas=[('D:\\ProgramData\\Anaconda3\\envs\\tempenv\\Lib\\site-packages','.')]
再次运行 pyinstaller -F predict.spec 成功不报错
运行 predict.exe 报错如下:
Traceback (most recent call last):
File "predict.py", line 6, in <module>
File "joblib\numpy_pickle.py", line 579, in load
with open(filename, 'rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'XGB2.pkl'
[10888] Failed to execute script 'predict' due to unhandled exception!
predict.py 第六行代码是 xgb = joblib.load('XGB.pkl'),应该是读取文件不成功,将XGB.pkl复制到 predict.exe 相同目录下。再次运行predict.exe,可以运行,问题解决。
期间尝试过其他方法,比如:
- 在Pyinstaller 命令中加入 --add-data,指定需要打包的数据,但是出错
- 在环境变量中加入虚拟环境路径,后发现不加入也可以打包不报错