Pyinstaller 打包exe遇到的各種問題及解決思路(詳細)


前言

  在使用python開發好一款軟件、工具之后,我們希望能夠把這個軟件發給其他人使用,就像我們使用其他軟件一樣,只需要雙擊打開exe,而不需要管其他環境。

對於類似C、C++而言是在系統編譯的時候就生成了exe,然后只需要把exe和所需環境一起打包即可。但是對於Python這種解釋型語言而言,不能通過這種方式生成可執行程序。

當然,python也有對應的處理辦法,其中常用的就是PyInstaller包。

PyInstaller介紹

      1. 安裝介紹

  PyInstaller包並不是python默認安裝模塊,需要用戶手動安裝,安裝方式如下:

pip install pyinstaller
#或
conda install pyinstaller
#對於一些裝不成功的模塊,可以考慮如下方式,以pydicom為例
conda install -c conda-forge pydico
pyinstaller -F -p XXX/Lib\site-packages XXX.py

  2.使用介紹

       切換到需要打包的python路徑下,然后再打包。是不是必須這樣需要打個問號,沒有做實驗,理論上應該只需要包含需要打包python文件全路徑即可,可能切換到文件路徑下更方便。

  PyInstaller 常用使用方式如下:

pyinstaller -F -w xxx.py

  -F: 打包成exe;-w:exe不顯示控制台,默認顯示(-c);xxx.py需要打包的python文件

       具體pyinstaller打包工具的詳細參數可以參考博文:https://blog.csdn.net/weixin_39000819/article/details/80942423

安裝成功后出現如下圖:

PyInstaller打包過程中遇到的問題及解決辦法

      1.打包后的exe出現閃退

    對於一個簡單的測試用例,打包完成后,雙擊exe之后就可以打開,如下圖所示:

 

   但是當你在程序中引用了其他包的時候,畫風就發生改變了,例如我在系統在中引入了numpy包,按照上面的方式打包,雙擊打開exe后就出現了閃退的情況

        剛開始的時候一頭霧水,完全不知道發生了什么,面對這種情況怎么處理呢?

2. exe閃退問題排查

  在這個時候打包的時候-c參數就起作用了,-c參數(默認參數)是打包成一個帶有后台的exe,可以看到調試信息、打印信息、報錯信息等,因此只需要把這個exe拖到cmd下面查看報錯信息就可以定位問題了。

 

 

   一看,發現是缺少numpy模塊。對於我不熟悉python打包的我,有點懵,還以為只需要按照上面的打包方式一頓操作就萬事大吉了,沒想到其實不是,也會遇到模塊丟失的問題,讓我想起的C++生成的exe,也是需要配套include、dll支持的。因此,猜測需要把所需要的模塊放到exe目錄下。

       我做了嘗試,但發現依然不起作用,當然有可能是我放置的路徑不對,或者包不全等原因。總而言之是沒成功!

3. 模塊缺失解決辦法(ModuleNotFoundError)

       可是如果真的要通過手動考包的方式考過去,會不會有點太麻煩,因此查到了另外的處理方式,也就是在打包的時候把依賴庫也打包進exe,不得不說這就是我期待的方式。

       那具體怎么操作呢?

       我們知道安裝的庫一般都是在"***/Lib\site-packages"文件夾中,也就是打包的時候把這個包打進去即可,看到很多博文提到這種方式確實解決了問題。

  例如這篇就寫得很好 https://www.cnblogs.com/Summerio/p/11676943.html

  廢話不多說,具體操作如下

pyinstaller -F -p ***/Lib\site-packages XXX.py

  看到這里,多了個-p參數,-p后面就是需要打包的庫路徑,這里是支持打包多個路徑的,只需要繼續-p +路徑即可。打包完成之后,可以看到新生成的exe的體積明顯更大了。

  但是很不幸,又遇到了其他的問題。打開exe依然失敗了。

        但是錯誤信息有些不一樣。

   這個就很詭異了,於是我看了下打包的過程中,是不是真的對了。結果還真是,打包的時候就出現問題了:

 這個就很奇怪了,看起來像是找不到numpy包,但我明明安裝了。為了證明這個猜想,我就用當前環境的python導入numpy試試看,發現還真不行。

4. python環境問題

 很是奇怪,因此我猜想是python環境的問題。python使用的庫site-package並不是當前環境的site-package(本人使用的是anaconda)。如下方式可以證明:

 (1)查看當前python路徑,確定環境

import sys
sys.executable

  

 

(2)查看當前python環境使用的site-package路徑

import site
site.getsitepackages()

  

 

 (3)結論:可以看到python並么有使用當前虛擬環境的site-packages,當前site-pacakges的路徑是D:\miniconda3\envs\testPackage\Lib\site-packages

因此引起了如上的錯亂。。。。

具體原因還沒有查到,看到一篇可能的原因是,conda沒有對用戶的site-packages,大家可以先看看

https://zhuanlan.zhihu.com/p/361712304

5. exe找不到包的子模塊,及對應解決辦法  

然而,真的是好事多磨,又遇到了其他問題了。因為我用到了pydicom這個模塊,發現打開exe后,找不到對應的子模塊:

 

很神奇,弄得我都懷疑這種打包方式對不對,不然為什么會找不到pydicom的子模塊。

不過幸好,找到了對應的解決辦法。也就是打包的時候,將找不到的模塊也一一打包進去:

pyinstaller -F -p D:\miniconda3\envs\fullPhaseSeparate\Lib\site-packages --hidden-import="pydicom.encoders.gdcm" --hidden-import="pydicom.encoders.pylibjpeg" main.py

  如上,使用--hidden-import="libname"的方式打包對應的子模塊。

具體參考文章如下:

https://newbedev.com/pyinstaller-modulenotfounderror-no-module-named-sklearn-utils-cython-blas#:~:text=Pyinstaller%20%3B%20ModuleNotFoundError%3A%20No%20module%20named%20%27sklearn.utils._cython_blas%27%20PyInstaller,use%20--hidden-import%20to%20add%20sklearn%20%27s%20missing%20modules.

 

成功

成功!激動之情溢於言表!

到這里為止!我這曲折的打包過程終於完事了!exe也發出去可以正常使用了!

希望對大家有絲絲幫助~

同時,歡迎大家溝通交流!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM