PyInstaller 打包 python程序成exe

 

 pychaim下PyInstaller 打包 python程序

主題是使用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 服務器

安裝與使用PyInstaller  

在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'],

 

結尾:引用請註明出處與做者

 

參考文獻: 

  1. http://www.javashuo.com/article/p-pqveadik-mx.html
  2. https://blog.csdn.net/qq_35614920/article/details/77096238
  3. https://github.com/fxsjy/jieba/issues/35
  4. https://pythonhosted.org/PyInstaller/spec-files.html#spec-file-operation
相關文章
相關標籤/搜索