| 參數 | 說明 |
|---|---|
| -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打包內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!