主題是使用PyInstaller 打包python時遇到一些問題以及解決方案,其中將要打包的程序是用tensorflow作的LSTM算法,這裏不會涉及這個算法詳解。html
本地環境:window 10 服務器環境 windows2008python
原文地址:原文git
python 3.6 github
PyInstaller 3.4算法
tensorflow 1.4 (過程當中更新爲1.7,緣由下詳)windows
jieba 0.39數組
wordcloud 1.5 服務器
在pychaim下能夠直接打開下方Teminal 窗口 執行指令 測試
pip install PyInstaller
打包python程序ui
PyInstaller -F XXXX.py
-F 是把全部的相關程序都打包成單個exe運行文件。
執行過程當中會在當前項目根目錄下 新建2個文件夾 build ,dist 與一個文件 XXXX.spec
build文件夾是在打包過程當中臨時存放全部中間文件的地方
dist是打包完成後的exe保存位置
XXXX.spec 與 打包時XXXX.py 是同名文件,自動生成了一份描述性文件,用來告訴pyinstaller 如何打包這個py程序。
因此一旦自動生成了一個spec文件 後續能夠根據需求自行修改 spec文件,而後執行
PyInstaller -F XXXX.spec
一,AttributeError: module ‘enum’ has no attribute ‘IntFlag
這個問題有文獻1可知,是因爲tensorflow 1.4 版本依賴了 enum34 這個庫致使的錯誤,因此我升級爲1.7 卸載掉了enum34庫
二,tuple index out of range
這個異常是由文獻2可知,pyinstaller當前版本不支持 python3.6 因此須要從GitHub那邊下載develop版本替換掉本地的版本。
三,No such file or directory: 'c:xxxx\jieba\dict.txt'
因爲接入了jieba庫,由於該庫裏面用到了一些默認的資源文件如 dict.txt idx.txt 等,
這個疑問參考issue 文獻3 ,可是解決方案治標不治本,另外還有不少資源文件都沒法加載 如:wordcloud 中就加載了默認的 stopword 停用詞字典。
由於在pyinstaller 打包後的exe 運行時會在 C:\Users\Administrator\AppData\Local\Temp 新增了一個臨時文件夾如「_MEIxxxxxx」 全部py代碼都會在臨時存放在這裏,
因此不少第三方庫中若是使用了 __file__ 以下示例:(wordcloud源碼)
FILE = os.path.dirname(__file__) FONT_PATH = os.environ.get('FONT_PATH', os.path.join(FILE, 'DroidSansMono.ttf')) STOPWORDS = set(map(str.strip, open(os.path.join(FILE, 'stopwords')).readlines()))
jieba庫也有相似加載方式。
會致使運行時__file__ 指向了上面說的臨時文件夾「_MEIxxxxxx」,因此就會報錯,說找不到該文件,沒法打開。
一勞永逸的辦法是修改 spec 文件.
先把一些須要加載的資源按照第三方庫默認的文件結構放在 static(這個名字隨你定) 文件夾內 ,以下圖
而後根據官方文檔參考文獻4,修改spec的datas 節點
datas接收一個元組數組 [(x1,y2),(x2,y2)] x1 是指須要打包的資源文件位置,能夠是文件夾名稱(我這裏是static),單一文件,或者 帶有通配符 * 的多個文件。 y1,是指須要輸出到臨時文件夾內的相對地址。這裏我用了 點符號,表明臨時文件夾自己。
這樣須要的資源文件就包括進去了,也能正常讀取了。
有其餘辦法是修改源碼的,實際上是很不優雅的。
四,No module named 'tensorflow.contrib'
這個異常在測試環境是沒有的,只有打包以後運行纔出現,緣由是tensorflow.contrib 這個庫是懶加載的,因此打包程序沒有包括進去,只有在運行時才發現少了。
這裏仍是能夠經過修改spec文件來隱性導入,就是上圖裏面的
hiddenimports=['tensorflow.contrib'],
結尾:引用請註明出處與做者
參考文獻: