總結Pyinstaller打包的高級用法
一、安裝pyinstaller
PyInstaller
是一個用來將Python
程序打包成一個獨立可執行文件的第三方包。
因是第三方包,所以需要安裝一下:
pip install pyinstaller
或者升級到最新版本:
pip install --upgrade pyinstaller
或者安裝開發者版本:
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.tar.gz
當然瞭,也可以下載whl
文件,然後pip install
安裝
更多可參考官網指引:
http://www.pyinstaller.org/downloads.html
二、打包初體驗
我們簡單試下打包python代碼為exe可執行文件,測試代碼如下:
# 測試.py import os path = os.getcwd() print(f'當前文件路徑:{path}') os.system('pause')
這段代碼是打印文件所在的目錄,我們用pyinstaller
簡單打包的命令如下:
pyinstaller -F 測試.py
這個命令,執行過程如下:
(env_test) F:\PythonCool\pyinstaller>pyinstaller -F 測試.py 403 INFO: PyInstaller: 4.3 403 INFO: Python: 3.8.10 (conda) 434 INFO: Platform: Windows-10-10.0.19042-SP0 436 INFO: wrote F:\PythonCool\pyinstaller\測試.spec 455 INFO: UPX is not available. 468 INFO: Extending PYTHONPATH with paths ['F:\\PythonCool\\pyinstaller', 'F:\\PythonCool\\pyinstaller'] 501 INFO: checking Analysis ... ... 15006 INFO: Appending archive to EXE F:\PythonCool\pyinstaller\dist\測試.exe 18999 INFO: Building EXE from EXE-00.toc completed successfully.
成功後會在同級目錄下生成一個dist
文件,裡面就是一個和代碼文件名同名的可執行文件:
雙擊該可執行文件,我們可以看到直接在python
解釋器裡運行測試.py
文件時一樣的結果:
這裡需要註意的是,我們在進行打包的時候,有必要指定被打包的py文件的路徑,兩種方式供選擇:
方式一:先切換到被打包py文件目錄,再執行打包指令
(base) C:\Users\Gdc>cd F:\PythonCool\pyinstaller (base) C:\Users\Gdc>F: (base) F:\PythonCool\pyinstaller>pyinstaller -F 測試.py
方式二:打包指令中指定py文件的絕對路徑
(base) C:\Users\Gdc>pyinstaller -F F:\PythonCool\pyinstaller\測試.py
關於成功打包的測試.exe
可執行文件,我們發現其圖標是默認的,且啟動時會顯示命令行窗口。那麼,我們可以怎麼自定義exe
圖標,又或者去掉命令行窗口呢?
三、打包進階體驗
好瞭,接下來,我們先看看關於pyinstaller
打包時候的一些別的參數都有哪些,如何自定義exe
圖標以及如何去掉命令行窗口等等。
(env_test) F:\PythonCool\pyinstaller>pyinstaller -h
pyinstaller -h
可以查看其參數說明,由於較多這裡不做完整展示,摘取部分常用參數做簡要介紹:
參數 | 說明 |
---|---|
-F | 產生單個的可執行文件 |
-D | 產生一個目錄(包含多個文件)作為可執行程序 |
-a | 不包含 Unicode 字符集支持 |
-d | debug 版本的可執行文件 |
-w | 指定程序運行時不顯示命令行窗口(僅對 Windows 有效) |
-c | 指定使用命令行窗口運行程序(僅對 Windows 有效) |
-o | 指定 spec 文件的生成目錄。如果沒有指定,則默認使用當前目錄來生成 spec 文件 |
-p | 設置 Python 導入模塊的路徑(和設置 PYTHONPATH 環境變量的作用相似)。也可使用路徑分隔符(Windows 使用分號,Linux 使用冒號)來分隔多個路徑 |
-n | 指定項目(產生的 spec)名字。如果省略該選項,那麼第一個腳本的主文件名將作為 spec 的名字 |
打包一個帶自定義icon的exe可執行文件
我們可以去這裡下載icon文件:
https://www.iconfont.cn/
可以去這裡將圖片轉化為icon文件:
https://www.bitbug.net/
然後,用一下命令可以自定義exe圖標:
(env_test) F:\PythonCool\pyinstaller>pyinstaller -F -i icon.ico 測試.py
成功後,我們可以看到圖標變成瞭我們自定義的這個:
打包去掉命令行彈窗的exe可執行文件
如果我們是有GUI的程序,想在啟動的時候去掉命令行窗口,那麼可以用以下指令進行打包,這裡以tkinter
內置GUI庫為例展示:
# 測試.py import tkinter top = tkinter.Tk() # 進入消息循環 top.mainloop()
以上測試代碼,如果用初體驗中的方式,在GUI界面出現的同時也會出現命令行彈窗,我們想去掉命令行彈窗可以:
(env_test) F:\PythonCool\pyinstaller>pyinstaller -F -w -i icon.ico 測試.py
雙擊打包後的exe
文件,可以看到隻會出現GUI界面,命令行窗口並沒有出現。
四、帶配置文件打包
所謂帶配置文件打包,這裡是指打包的時候除瞭py文件、依賴的庫之外,還存在需要引用的其他資源文件。直接用以上方式打包的時候,這些資源是無法被打進包的,我們需要進行修改打包時的spec
文件來實現。
spec文件是告訴Pyinstaller怎麼打包py文件,比如路徑、資源、動態庫、隱式調用的模塊等等。一般來說,我們不需要對它進行修改…
這裡我用此前《詞雲繪制小工具》的案例來進行介紹。
我們直接用打包進階體驗中的命令可以進行成功打包,不過這裡我們發現有兩個問題:①包體很大,比此前案例裡大瞭10倍左右;②啟動exe文件的時候報錯瞭。
關於包體較大的情況,可以試著創建虛擬環境,然後隻安裝程序裡需要調用的庫即可,這裡隻簡單介紹:
# 創建虛擬環境 conda create -n your_env_name python=3.8.10 # 啟動虛擬環境 activate your_env_name
關於啟動報錯的情況,由於比較復雜,我們一步一步來看:
①由於無命令行彈窗,無法查看到具體的報錯,這裡先去帶命令行窗口形式看下報錯信息,我們看報錯如下:
提示缺少這個文件,我們可以在打包生成的詞雲繪制工具.spec
配置文件裡將這個資源放上
# -*- mode: python ; coding: utf-8 -*- # 詞雲繪制工具.spec block_cipher = None a = Analysis(['詞雲繪制工具.py'], pathex=['F:\\PythonCool\\pyinstaller'], binaries=[], datas=[], # 這裡帶上資源文件地址 hiddenimports=[], # 動態引入的庫或模塊 hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='詞雲繪制工具', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=True , icon='icon.ico')
通過在wordcloud
模塊目錄裡查到瞭stopwords
文件,我們將其放到data中。
datas=[('C:\\Users\\Gdc\\anaconda3\\envs\\env_test\\Lib\\site-packages\\wordcloud\\stopwords','wordcloud')],
前者是資源文件在本機的位置,後者為打包後文件調用的相對路徑,編輯好spec
文件後,通過以下命令進行打包:
(env_test) F:\PythonCool\pyinstaller>pyinstaller -D 詞雲繪制工具.spec
好吧,還有一些文件未被打進包,所以又出現同樣的問題瞭。所以,我們是需要把全部的資源文件都加到spec文件裡的data中。
我們找到全部的資源文件全部加上吧,然後再執行打包命令。
datas=[('C:\\Users\\Gdc\\anaconda3\\envs\\env_test\\Lib\\site-packages\\stylecloud\\static','stylecloud\\static'), ('C:\\Users\\Gdc\\anaconda3\\envs\\env_test\\Lib\\site-packages\\wordcloud\\stopwords','wordcloud'), ('C:\\Users\\Gdc\\anaconda3\\envs\\env_test\\Lib\\site-packages\\jieba\\analyse\\idf.txt','jieba\\analyse'), ('C:\\Users\\Gdc\\anaconda3\\envs\\env_test\\Lib\\site-packages\\jieba\\dict.txt','jieba')]
我們將配置資源打進包後可以正常啟動exe可執行文件瞭。
但是,又發現在執行詞雲繪制的時候,也會出現報錯。不過看報錯的情況是提示不存在xx模塊
,那麼這是什麼情況呢?!
五、添加隱式調用庫
我們找到報錯的地方代碼如下,采用瞭__import__()
函數用於動態加載類和函數palettable
模塊。
def gen_palette(palette: str): """Generates the corresponding palette function from `palettable`.""" palette_split = palette.split(".") palette_name = palette_split[-1] # https://stackoverflow.com/a/6677505 palette_func = getattr( __import__( "palettable.{}".format(".".join(palette_split[:-1])), fromlist=[palette_name], ), palette_name, ) return palette_func
對於這個問題,我試過兩種方案,大傢可以參考一下。
方案一:在spec文件中hiddenimports中添加動態引用的模塊
hiddenimports=['palettable'], # 動態引入的庫或模塊
這種情況下,palettable
庫裡也有一些配置文件需要添加到spec文件裡的data中
('C:\\Users\\Gdc\\anaconda3\\envs\\env_test\\Lib\\site-packages\\palettable\\colorbrewer\\data','palettable\\colorbrewer\\data')
方案二:修改stylecloud庫中調用palettable模塊的代碼部分
import palettable def gen_palette(palette: str): palette_func = getattr(palettable.tableau,'BlueRed_6') return palette_func # """Generates the corresponding palette function from `palettable`.""" # palette_split = palette.split(".") # palette_name = palette_split[-1] # https://stackoverflow.com/a/6677505 # palette_func = getattr( # __import__( # "palettable.{}".format(".".join(palette_split[:-1])), # fromlist=[palette_name], # ), # palette_name, # )
通過第4和5部分,我們用pyinstaller終於成功打包且正常運行使用瞭。
以上就是本次全部內容,大傢如果遇到打包時涉及到配置文件的或者隱式調用的,可以采用這兩個2技巧進行特殊打包!
不過,關於pyinstaller打包其實還有更多操作,大傢可以多看看官方文檔瞭解,主要是命令行參數及spec文件裡的配置要點。
到此這篇關於總結Pyinstaller打包的高級用法的文章就介紹到這瞭,更多相關Pyinstaller打包內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- python之pyinstaller組件打包命令和異常解析實戰
- pyinstaller pathex參數引發打包no module name異常
- pyinstaller打包可執行文件,存放路徑包含中文無法運行的解決方案
- Python Pyinstaller庫安裝步驟以及使用方法
- Pyinstaller打包文件太大的解決方案