寫了一個(gè)Python的小程序,用到了PYQT5和pandas治拿。想用pyinstaller做成.exe文件摩泪,中間一直報(bào)錯(cuò),折騰了一晚上加半個(gè)早晨劫谅,總算解決了见坑。
遇到的問題如下:
自己寫了3個(gè).py文件嚷掠,具體名字不說了,假設(shè)是a.py荞驴、b.py不皆、c.py,其中a.py是UI熊楼,import了b.py霹娄;b.py又import了c.py。
先后報(bào)了三個(gè)錯(cuò)誤鲫骗,分別是Failed to execute script犬耻、 no module named 和 'utf-8' codec can't decode byte,具體問題的出現(xiàn)和解決過程是這樣的:
1.
直接用 pyinstaller -F -w a.py:可以生成.exe文件执泰,但執(zhí)行exe報(bào)Failed to execute script枕磁。
2.
想知道具體是為什么失敗的,于是改用命令pyinstaller -F a.py(去掉了-w參數(shù)术吝,因?yàn)橄朐诿钚写翱诳吹降资鞘裁村e(cuò)誤)计济。報(bào)no module named錯(cuò)誤,如下圖所示(如果命令行窗口一閃而過排苍,手快的話可以迅速按‘print screen’鍵截屏沦寂,再粘貼到word里放大看是什么錯(cuò),圖中的UI_main.py就是前面討論的a.py)
發(fā)現(xiàn)是pandas的問題淘衙,GitHub上有個(gè)討論給了一個(gè)寫hook-pandas的解決方法(鏈接:https://github.com/pyinstaller/pyinstaller/issues/2137)传藏,照做了,依然報(bào)錯(cuò)幔翰。
又發(fā)現(xiàn)CSDN上有討論漩氨,提到應(yīng)當(dāng)加參數(shù)--hidden-import(鏈接:https://blog.csdn.net/jeff_/article/details/72907113),于是加了參數(shù) --hidden-import pandas遗增,成功解決與pandas相關(guān)的no module named 錯(cuò)誤叫惊,此時(shí)使用的命令為:pyinstaller --hidden-import pandas -F a.py
3.
此時(shí)運(yùn)行生成的exe,依然報(bào)錯(cuò)做修,但是錯(cuò)誤變了霍狰,變成了與c.py相關(guān)的no module named 錯(cuò)誤如下圖所示(item_similarity就是所謂的c.py)
這時(shí)候覺得很奇怪,b.py沒有報(bào)錯(cuò)饰及,但c.py報(bào)錯(cuò)了蔗坯,也沒什么別的頭緒,于是嘗試與pandas類似解決燎含,增加--hidden-import c宾濒,即使用命令pyinstaller --hidden-import pandas --hidden-import c -F a.py泥从,但是這一次問題沒有解決剑辫,依然報(bào)c.py相關(guān)的no module named。
4.
想到是不是可以把3個(gè).py文件都放在命令,嘗試一次打包3個(gè)文件哺壶,即使用命令pyinstaller --hidden-import pandas -F a.py b.py c.py拐邪,但這一次pyinstaller沒有成功生成.exe文件睬塌,而是報(bào)了一個(gè) 'utf-8' codec can't decode byte錯(cuò)誤庐船。
只好繼續(xù)上網(wǎng)查解決辦法,找到了https://www.dlology.com/blog/solution-pyinstaller-unicodedecodeerror-utf-8-codec-cant-decode-byte/榄棵,其中提到了修改python35\lib\site-packages\PyInstaller\compat.py凝颇,照做了,但問題還是沒有解決疹鳄。
另外還有文章提到拧略,報(bào)這個(gè)錯(cuò)的時(shí)候把中文注釋刪掉就可以解決。想了一下尚辑,a.py中也有中文注釋辑鲤,但是之前生成exe的時(shí)候并沒有報(bào)utf-8的錯(cuò)誤。也就是說杠茬,在utf-8的問題上,a.py和c.py時(shí)出現(xiàn)了分歧——》 這說明a.py和c.py可能在utf-8的問題上有不同 ——》 回頭查看a.py和c.py的源代碼——》果然弛随,c.py中忘記寫 #-*- coding:utf-8 -*- 了……由于使用的IDE沒有報(bào)錯(cuò)瓢喉,所以我一直都沒發(fā)現(xiàn)這個(gè)問題……
在c.py加上 # -*- coding:utf-8 -*- 之后,再使用命令 pyinstaller --hidden-import pandas -F a.py舀透,成功得到可以正確執(zhí)行的exe文件栓票。
5.
小結(jié)一下。前后報(bào)了兩次no module named 錯(cuò)誤愕够,但引發(fā)該錯(cuò)誤的原因是不同的走贪,這里猜測(cè)一下錯(cuò)誤原理(由于對(duì)pyinstaller的內(nèi)部原理了解的不多,所以可能說的不對(duì)惑芭,歡迎指正):
對(duì)于pandas來說坠狡,no module named 錯(cuò)誤是因?yàn)閜yinstaller沒有直接包含與pandas相關(guān)的處理方法,所以需要顯式指明--hidden-import pandas(增加hook-pandas文件不知道起沒起作用遂跟,后來我也沒有再刪除它)逃沿。
對(duì)于自己寫的c.py來說,no module named錯(cuò)誤是因?yàn)閏.py的源文件里面出現(xiàn)了一些(潛在的)錯(cuò)誤幻锁,這些錯(cuò)誤對(duì)于某些IDE來說可能是可以處理或忽略的凯亮,但是pyinstaller的解釋器并不能處理這些錯(cuò)誤,于是c.py分析失敗哄尔,出現(xiàn)關(guān)于c.py的no module named 錯(cuò)誤假消。
因此,當(dāng)遇到某類錯(cuò)誤發(fā)生在不同位置岭接,又沒法用同一種策略解決時(shí)富拗,可以多試幾種不同的(如果可以堂鲤,最好是等價(jià)的)命令,看是否會(huì)報(bào)不一樣的錯(cuò)誤媒峡,一旦發(fā)現(xiàn)之前沒報(bào)過的新錯(cuò)誤瘟栖,從新錯(cuò)誤出發(fā)思考,也許會(huì)得到解決思路谅阿。