使用Pyinstaller打包多個文件與資料夾
>使用Pyinstaller打包多個文件與資料夾到單一執行檔
指令的介紹
在 Windows 系統中使用Pyinstaller非常簡單,尤其是只有包含一個主程式(.py檔案)
pyinstaller main.py
執行完此一程式後,會生成兩個資料夾 build 和 dist,build裡面會寫入log檔案和工作檔案,dist裡面會寫入main.py的可執行檔,並且生成一個以第一個.py檔名命名的.spec檔案
舉例來說 :
pyinstaller main.py
會生成一個main.spec以及一個./dist/main.exe
然而對於需要調用其他目錄下資料的Python程式,例如 :
main_folder/
│
├── main.py # Flask 後端程式
├── templates/
│ ├── form.html # 表單頁面(前端)
│ └── result.html # 顯示生成 Prompt 結果
├── static/ # (可放 CSS/JS 資源)
└── README.md # 專案說明文件
如果不強求把它封裝成單一的執行檔,也就是執行檔與整份資料夾的結構不能有路徑的變化,那可以維持IDE模式下的相對路徑。
這也是pyinstaller預設的封裝方式 -D, --onedir
但如果想要把所有資料完整的封裝成一個單一的執行檔,則需要 -F, --onefile 這道指令
而且如果主程式 main.py 會需要調用目錄中templates/下的所有檔案,就不能單單只用一行指令混過去了。
而是需要增加如以下使用--add-data這個指令
pyinstaller main.py -F --add-data "templates;templates"
接著詳細講解 --add-data 的使用方式
--add-data "Source;Dest"
Source代表你要打包的檔案或資料夾Dest代表打包之後這個檔案的相對位址;為分隔的作用,這裡需要注意,在window系統中是使用;進行分隔,Linux和macos則是使用:。
# Windows
pyinstaller main.py --add-data "Source;Dest"
# macOS / Linux
pyinstaller main.py --add-data "Source:Dest"
如果你希望你的檔案打包後直接安裝在跟目錄可以使用 . 作為 Dest 如下
--add-data "Source;."
並且 --add-data 這個指令是不限次數的,可以視需求一次使用多個,但都要各自分別指定。
如以下 :
pyinstaller main.py --add-data "Source1;Dest1" --add-data "Source2;Dest2"
程式碼的改動
當目標檔案被打包後,檔案的路徑就改變了,會與使用IDE下執行的路徑不同。
os.path.join('main_folder', 'templates') #IDE模式下的路徑
在pyinstaller的打包流程下,所有打包後的檔案會出現在臨時資料夾 sys._MEIPASS 內,資料的相對路徑則依照上面的 Dest 指定。
這時須將python程式碼內的路徑重寫,改寫如以下的路徑 :
os.path.join(sys._MEIPASS, 'templates')#調用整個templates資料夾
並且pyinstaller的 --add-data 的指令如以下 :
pyinstaller main.py --add-data "templates;templates"
在IDE與封裝模式下手動更改路徑是麻煩的,可以將Python的路徑判斷函數寫成以下 :
import sys, os
def resource_path(relative_path):
if hasattr(sys, '_MEIPASS'):# 檢測是否有封裝後的臨時資料夾
return os.path.join(sys._MEIPASS, relative_path)# 生成路徑
else:
return os.path.join(os.path.abspath("."), relative_path)# IDE模式下的路徑
這裡需要注意relative_path的名稱要與Pyinstaller --add-data 的 Dest 路徑相同。
打包模式比較
| 模式 | 描述 | 優點 | 缺點 | 是否需要 sys._MEIPASS |
|---|---|---|---|---|
| --onedir(預設) | 輸出為一個資料夾,內含 EXE 與所有依賴檔案 |
|
|
否 |
| --onefile | 輸出為單一 EXE,執行時解壓縮到暫存資料夾 |
|
|
是 |
留言
張貼留言