轉載:https://zhuanlan.zhihu.com/p/65731845
pyinstaller最佳使用方式
pyinstaller最重要的兩個參數就是-F與-D參數
使用-F參數,pyinstaller會將python腳步打包成單個exe文件
使用-D參數,pyinstaller會將python腳步打包成一個文件夾,運行程序時,需要進入該文件夾,點擊運行相應的可執行程序
此前爲了美觀,開源通過 -i 參數指定程序的icon(圖標),但這個命令只在windows下生效,本人MacOS上是沒有作用的,同時可以使用 -n 參數定義打包後文件的名稱
如果你自己通過PyQt5或tkinter開發了界面,此時通常不希望在運行時彈出命令行,如windows下的cmd命令行,此時可以使用-w參數
綜上所述,我最常用的命令爲
pyinstall -i xxx.ico -n xxx -w -D main.py
其中 -D 參數或 -F 參數後面跟的是入口文件,即你 python xxx.py
運行程序時這個xxx.py文件
對應依賴比較多的程序,建議使用 -D, -F更適合單文件的py腳本。
pyinstaller 打包其實分兩步走,第一步,就是通過上面的命令執行打包,此時會生成相應的spec文件,大體流程如下:
1、在腳本目錄生成 xxx.spec 文件(看-n參數,沒傳,則與xxx.py同名爲xxx); 2、創建一個 build 目錄; 3、寫入一些日誌文件和中間流程文件到 build 目錄; 4、創建 dist 目錄; 5、生成可執行文件或文件夾到 dist 目錄;
效果如下:
第一步完成後,獲得xxx.spec,然後再執行
pyinstaller xxx.spec
完成打包
進入dist中打包好的文件夾後,雙腳運行可執行文件則可
圖片上傳失敗
效果如下:
圖片上傳失敗
這是一個利用tkinter構建界面的簡單程序
spec文件解析
一個spec文件的例子。
block_cipher =
None
a =
Analysis(['minimal.py'],
pathex=['/Developer/PItests/minimal'],
binaries=None,
datas=None,
hiddenimports=[],
hookspath=None,
runtime_hooks=None,
excludes=None,
ciper=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
...)
coll = COLLECT(...)
spec文件中主要包含4個class: Analysis, PYZ, EXE和COLLECT.
- Analysis以py文件爲輸入,它會分析py文件的依賴模塊,並生成相應的信息
- PYZ是一個.pyz的壓縮包,包含程序運行需要的所有依賴
- EXE根據上面兩項生成
- COLLECT生成其他部分的輸出文件夾,COLLECT也可以沒有
時候PyInstaller自動生成的spec文件並不能滿足我們的需求,最常見的情況就是我們的程序依賴我們本地的一些數據文件,這個時候就需要我們自己去編輯spec文件來添加數據文件了。 上面的spec文件解析中Analysis中的datas就是要添加到項目中的數據文件,我們可以編輯datas.
a =
Analysis(
...
datas =
[('you/source/file/path','file_name_in_project'),
('source/file2',
'file_name2')]
...
)
可以認爲datas是一個List,每個元素是一個二元組。元組的第一個元素是你本地文件索引,第二個元素是拷貝到項目中之後的文件名字。除了上面那種寫法,也可以將其提出來。
added_files =
[...]
a =
Analysis(
...
datas = added_files,
...
)
這一節內容來自pyinstaller簡潔教程
注意事項
避免打包後,包文件過大
爲了避免 pyinstaller 打包後程序或文件夾過大,如:幾百kb的程序打包後編程500M左右的程序,在引用包時,儘量使用 from ... import ... 語句,這是因爲pyinstaller打包的路徑其實是將python解釋器以及項目中使用的庫直接複製過來,所以如果你沒事就 import... ,那麼pyinstaller會將整個模塊複製過去,此時打出來的包就會很大
考慮路徑問題
使用python時,要養成使用 os.path.join 的習慣,這不僅可以避免跨平臺的路徑坑(windows路徑表達與類Unix是不同),又可以在打包時不會出現相對路徑的問題,很多python程序員編寫路徑喜歡使用 + 號來鏈接路徑,這會增加項目的維護成本
pyinstaller 打包的項目遇到路徑都使用 os.path.join 則可
外部數據問題
雖然在上節中,提及了使用外部數據時,可以自定義 spec 文件中的 datas 字段,但我更常用的做法是直接將數據複製過去,不去修改datas。
比如我的項目中依賴 config 文件夾下的配置文件,執行將 config 文件夾整體直接複製到打包好的文件夾中則可
閃屏結束
如果是簡單的程序,可能會出現運行可執行程序後出現一閃而過的情況,這種情況下要麼是程序運行結束(比如直接打印的 helloWorld),要麼程序出現錯誤退出了。
這種情況要麼通過 input() 函數捕捉輸入自己主動結束程序,要麼就在 cmd 下運行 exe 文件,從而通過 cmd 看到效果