在使用pyinstaller将python打包成exe的过程中,遇到了ModuleNotFoundError的问题,私以为可以分别几类,可能还有余未遇Bug,暂且将我遇到的,怎么解决的记录下来。
1. 运行路径
有时会在自己的代码,或者在第三方库中出现下面类似的代码,
lib_path = __file__[:-11] + 'core/'
if lib_path not in sys.path:
sys.path.append(lib_path)
from awGA import awGA
from boundfix import boundfix
from bs2int import bs2int
其原因是在pycharm中运行和生成exe之后os.path.dirname(__file__)返回的位置不一样。
解决方案:
(1)直接设置lib_path路径,比如我这里就是
lib_path = 'D:\***\***\Python36\lib\site-packages\geatpy\core/'
(2)获取exe执行文件所在路径,将第三方库放在一个目录下
lib_path = os.path.dirname(os.path.realpath(sys.executable)) + '/site-packages/geatpy/core'
其中 os.path.dirname(os.path.realpath(sys.executable)) 可以获取exe执行文件所在路径,geatpy是我需要的第三方库,由于我这里还需要再往下深一级到core文件夹下所以我这里还有‘/core’。
2. 第三方库中的import
第三方库有时也引用其他的库,也会有 ModuleNotFoundError 的问题,
解决方案:
修改***.spec文件中的datas参数。
Analysis(datas=[('D:\\***\\***\\untitled\\venv\\Lib\\site-packages', '.')],)
其中 'D:\\***\\***\\untitled\\venv\\Lib\\site-packages' 就是存在第三方库的目录,最后的 '.' 是不能少的,还有就是看清楚两个字符串外有小括号(),没有这个小括号的话就会报错 ValueError: too many values to unpack。
然后使用这个spec文件打包就可以了,打包命令:
pyinstaller --hidden-import=pkg_resources -F main.spec main.py
3. 加载模型
这种情况是模型已经训练好并且保存后,在使用训练好的模型时出现 ModuleNotFoundError 。比如:
pickle_in = open(modelPath, 'rb')
model = pickle.load(pickle_in)
model.predict(datas)
解决方案:
首先import第三方库,我这里就说import xgboost。
然后做一下上面的第二种情况,就OK了。