今天俺试图把依赖torch的.py用Pyinstaller打包成exe运行,却发生了很多问题。下面给大伙分享一下解决方法:
问题一:WARNING:file already exists but should not:C:\Users\administrator\AppData\Local\Temp\_MEI296842\_C.cp39-win_amd64.pyd
这个问题可以参考这一篇文章 http://t.csdn.cn/h1SNB,概括来说就是这个BUG没啥影响,但是不想让它弹出的话可以在打包之后得到的spec文件里增加这一段代码:
······noarchive=False) # 上接代码
for d in a.datas:
if '_C.cp39-win_amd64.pyd' in d[0]:
a.datas.remove(d)
break
pyz = PYZ(a.pure, a.zipped_data,······ # 下接代码
随后cmd来到spec所在目录,输入以下指令:
pyinstaller xxxx.spec
等待重新打包好,再次运行即不会再次弹窗。
问题二:WARNING:file already exists but should not:C:\Users\administrator\AppData\Local\Temp\_MEI296842\torch\_C_flatbuffer.cp39-win_amd64.pyd
这个问题同上个问题一样,也是一样的解决方法,在spec文件中加入下行代码:
······noarchive=False) # 上接代码
for d in a.datas:
if '_C_flatbuffer.cp39-win_amd64.pyd' in d[0]:
a.datas.remove(d)
break
pyz = PYZ(a.pure, a.zipped_data,······ # 下接代码
再重新pyinstaller一下spec就可以了。
问题三:Failed to execute script 'main' due to unhandled exception:[Errno 2] No such file or directory:'checkpoint.pth'
Traceback (most recent call last):
File "main.py", line 15, in <module>
File "torch\serialization.py", line 699, in load
with _open_file_like(f, 'rb') as opened_file:
File "torch\serialization.py", line 230, in _open_file_like
return _open_file(name_or_buffer, mode)
File "torch\serialization.py", line 211, in __init__
super(_open_file, self).__init__(open(name, mode))
FileNotFoundError: [Errno 2] No such file or directory: 'checkpoint.pth'
类似的问题我之前在打包依赖Mediapipe的项目时候出现过,当时Error的是No such file or directory: 'mediapipe/solutions',原因是打包的时候mediapipe的solutions没有跟着一起打包进exe里。之前的解决方法是在打包时加上--adddata指令:
pyinstaller -F -w main.py --add-data="(想要打包的文件在电脑的位置);(exe中依赖文件的位置)"
于是这次我还是这样子把这次缺失的.pth文件如以下代码加了进去:
pyinstaller -F -w main.py --adddata="D:/Python/PythonProject/virualman/checkpoint.pth;./checkpoint.pth"
结果还是会报相同的错误。找了很多方法,感觉是打包后没有正确访问导.pth文件,路径不对的问题。于是在原来的.py文件中读取pth文件地址之前加入了以下代码:
if getattr(sys, 'frozen', False):
cur_path = sys._MEIPASS # pyinstaller 打包后所有依赖文件的根目录
else:
cur_path = os.path.dirname(__file__)
model_path = os.path.join(cur_path, 'pth/checkpoint.pth') # 这时是所有依赖文件的根目录下pth文件的路径
之前.pth文件是跟main.py在同一目录下,现在创建一个空的文件夹,并将.pth文件放在其中,随后再次打包,这次--adddata也与之前不同:
pyinstaller -F -w main.py --adddata="D:/Python/PythonProject/virualman/pth;pth"
也就是说不能直接添加所需的文件,需要放在某个文件夹下随后将文件夹添加进exe里:
这一次就可以正常运行啦!
除了以上的方法,还可以把.pth文件拖到dist文件夹以下,手动补充没有打包进去的数据。不过移动exe到其他目录下运行,也需要移动.pth文件,而且有可能报错。