目的:將python項目打包成exe文件。
項目特點:該python項目包含多個子文件夾及py文件,與外部有xml數據交換。
使用的庫:pyqt5,numpy,matplotlib,opencv-python,scikit-learn
方法:新建虛擬環境,使用pyinstaller
進行打包,避免在anaconda環境下打包體積過大。
問題:anaconda下打包的exe文件約200Mb,新建環境後體積有減小,但是仍然有100Mb。下一步嘗試使用UPX
壓縮、在visual studio下用C++封裝後打包、用python-embedded…
步驟
1、新建virtualenv環境,並激活環境
由於anaconda會自帶很多不需要用的庫,所以直接在開發的環境下打包會導致打包之後的exe文件體積過大,因此在cmd下用系統自帶的python新建虛擬環境,只安裝必須的庫。
1)在cmd窗口下,輸入python
,如下圖,確定python版本與開發環境是一致的。
Tips:
- 如果安裝了python,提示指令出錯,將python.exe所在的目錄加入系統環境變量中;
- 如果顯示的是anaconda的python,可以將anaconda所在的環境變量刪掉,或者將官方版python在環境變量中的位置放在anaconda之前;
2)在cmd下,安裝virtualenv用於創建獨立的python環境;
pip install virtualenv
3)cd
選擇一個路徑,在該路徑下建立新的、乾淨的python環境;
virtualenv your_env # your_env 自行命名
4)cd
切換到新建環境中的scripts路徑下(eg. E:\your_env\Scripts
),輸入activate
激活環境;
5)cd
切換到程序目錄,該目錄下有程序的入口,比如main.py
2、結合pyinstaller,安裝必要的庫
1)使用pip安裝項目中使用到的庫;
pip install pyqt5 numpy matplotlib opencv-python scikit-learn
2)使用pyinstaller嘗試打包,記下顯式缺少的庫(eg. ModuleNotFoundError
),再通過pip安裝;
pyinstaller -F main.py
比如出現如下信息:
ModuleNotFoundError: No module named 'win32com'
,經查詢,是由於缺少pywin32
庫。直接通過
pip install pywin32
安裝即可。
3)如果執行成功,當前路徑下將會多出3個文件:./build
、./dist
、main.spec
3、修改.spec
文件,加入缺失的dll、module
1)cd
切換到dist路徑下,運行main.exe
,對於簡單的項目,這一步可能直接成功運行,則到此爲止。若運行不成功,會出現錯誤提示,根據提示繼續下一步;
2)如果提示....PyInstallerImportError: Failed to load dynlib/dll...
,則找到該dll文件,放在當前程序文件夾中,將main.spec
的datas
修改如下:
# 例子, 第一個引號表示dll名,第二個引號表示路徑
datas=[('vcomp140.dll','.'),('MvCameraControl.dll','.')],
3)如果提示ModuleNotFoundError: No module named 'sklearn.utils._cython_blas'
,由於這是在sklearn中的子模塊,不能通過pip安裝,需要將main.spec
中的hiddenimports
修改如下:
hiddenimports=['sklearn.utils._cython_blas'],
4)修改之後重新編譯,需要先將./build
和./dist
文件夾刪掉,再用pyinstaller指令,指令中的main.py
改成main.spec
。
pyinstaller -F main.spec
4、將依賴數據(比如用於持久化的數據./data
)和main.exe
放在一個文件夾下,即可運行。
debug:
ModuleNotFoundError: No module named 'pkg_resources.py2_warn'
需要降低setuptools
的版本。
Tips:
設置國內鏡像,提升pip下載速度
在環境變量Home
對應的文件夾中新建一個./pip/pip.ini
文件,加入如下內容:
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=mirrors.aliyun.com