1. 程式人生 > >Windows下利用pyinstaller打包Python3.6指令碼

Windows下利用pyinstaller打包Python3.6指令碼

最近用python寫了一個TensorFlow程式,基於谷歌的facenet來檢測人臉,我寫的是伺服器端,包括一個tcp通訊協議,問題來了,如何將其打包成一個exe檔案釋出?

本人電腦:

Windows 10 系統;

Python 3.6.3(Anaconda 3.5.0.1安裝);

TensorFlow 1.4.0(GPU版本,1050Ti)

PyInstaller 3.3.1

0、入坑前的準備工作

網上最為流行的就是PyInstaller方法了,我決定使用這個方法將我的py檔案打包成exe。首先,明確最新版的pyinstaller已經支援python3.6版本的打包工作,我們可以登入PyInstaller的官網看看下面的訊息:


截止本人寫這篇部落格,最新版的PyInstaller是3.3.1:


使用pip安裝步驟非常簡單,就是一步:

pip install pyinstaller

然後使用也很簡單,在windows下按Win+R進入命令列,輸入cmd,然後進入你的py檔案所在的資料夾:(我的程式放在了桌面的AeyeFaceDetection_python資料夾內)

cd desktop\AeyeFaceDetection_python

接著使用下面的命令生成exe檔案:

pyinstaller -F main.py

用-F意味著可以生成單個可執行檔案,如果是下面的方法:

pyinstaller -F -w main.py

則表示去掉控制檯視窗,這在GUI介面時非常有用。不過如果是命令列就不要這樣寫。

現在我們假設已經按照-F方法生成成功,那麼在我們的py檔案所在的資料夾內可以看到兩個新生成的資料夾,名字為build和dist,並且在我們要生成的py檔案下有一個同名的spec檔案,這個檔案的作用在網上可以百度的到,我這裡就不作敘述了。

1、第一個坑:requests版本問題

我按照官方教程和各位網友的操作,發現第一個問題就是這樣的:

  File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\utils\hooks\__init__.py", line 619, in collect_submodules
    repr(pkg_dir), package))
  File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\utils\hooks\__init__.py", line 90, in exec_statement
    return __exec_python_cmd(cmd)
  File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\utils\hooks\__init__.py", line 77, in __exec_python_cmd
    txt = exec_python(*cmd, env=pp_env)
  File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\compat.py", line 588, in exec_python
    return exec_command(*cmdargs, **kwargs)
  File "d:\software\anaconda3.5.0.1\lib\site-packages\PyInstaller\compat.py", line 378, in exec_command
    out = out.decode(encoding)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 125: invalid continuation byte

由於問題過於龐雜,不太好找原因,我就先寫了小的測試指令碼,命名為d.py,放在原資料夾下:

import time
print("zhangping is a man.")
time.sleep(5)

注意這裡的延時是必要的,否則程式會一閃而過,就類似於C++中新增一個getchar()一樣。

執行

pyinstaller -F d.py

發現可以成功,如下圖:


就走我以為一切都順利的時候,執行C:\Users\zhangping\Desktop\AeyeFaceDetection_python\dist\d.exe,發現程式崩潰:


這個問題在網上我搜了好久,包括增加環境變數等各種方法都嘗試過了,都沒有用,最後找到了這個:

完美解決的方法如下:

(1)首先要檢視自己的requests版本,高於2.10就自行解除安裝:


(2)解除安裝:

pip uninstall requests

(3)重新安裝requests2.10.0版本:

pip install requests==2.10.0

再次打包就可以執行d.exe了。

然而打包main.py還是報錯。

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 125: invalid continuation byte

2、第二個坑:UnicodeDecodeError: 'utf-8' 問題

網上好多方法均不可行,因為我的路徑下沒有任何中文,(雖然我的人臉資料庫中的庫中人名是中文),但網上很多的這種解決方案是不適合我的。

用管理員許可權是無法解決這個問題的。還是會報這個錯誤。

在查找了很多文章後,我看見了這個:

我按照他的思路,首先改變編碼格式,先輸入chcp 65001,表示使用UTF-8。

chcp 65001

然後執行:


最後顯示打包成功!


3、第三個坑:import matplotlib問題

原以為打包成功,結果我雙擊C:\Users\zhangping\Desktop\AeyeFaceDetection_python\dist\main.exe,遇到這樣的問題:


其實這個問題在上面那個連結裡面就已經有寫了。但他寫的方法只能對matplotlib在打包時候不出錯,但不能使程式在執行時不出錯!!!

根據錯誤的提示,在main.py的第8行,我找到了這句程式碼:

import matplotlib.pyplot as plt

很湊巧的是,這句程式碼和我的程式無關,當初加進來也沒用上,所以我就直接刪除了。

然後再次打包,執行exe檔案,完美!

4、綜上:

(1)要注意看看自己的requests版本,不出意外的話都說比較高的版本,要解除安裝,重灌為2.10.0版本;

(2)要改變編碼格式,先輸入chcp 65001;

(3)要注意程式中是否出現了matplotlib的引入,如果有,則繼續尋找解決辦法(我沒用到,就沒有繼續深究了)

(4)程式所在的目錄最好不出現中文。





5、新坑:

AttributeError: module 'enum' has no attribute 'IntFlag'問題

https://blog.csdn.net/qq_41185868/article/details/80599336

6、新坑:

Maximum recursion depth exceeded 問題

https://blog.csdn.net/Sagittarius_Warrior/article/details/78457824

7、新坑:

AttributeError:type object 'pandas._libs.tslib_TSObject' has no attribute '__reduce_cpython__' 問題

尚未解決