本篇文章同步發布於 如何使用 PyInstaller 將 Python 專案打包成 exe 執行檔?【Python 處理 Excel #28】
因為工作場合的同部門同事幾乎沒有學過程式,甚至完全不知道 Python 是什麼,儘管很樂意將用 Python 寫好的 Excel 處理工具提供給他們使用,如果需要讓他們操作程式編輯器的介面或調整參數,上手的門檻就太高太複雜,我希望能讓他們無腦使用這些工具。
在提供網頁版的使用者介面或一般桌面應用程式之間,我選擇了後者,使用 Python 內建的 Tkinter 套件寫一個基本的介面,然後就可以將整個專案打包起來,讓同事用滑鼠點個幾下就能得到想要的結果。畢竟不用再麻煩 MIS 開放一個伺服器讓我部署網站,我覺得是現有條件下最便捷的方案。
這篇文章介紹如何使用 Python 的 PyInstaller 套件將 Python 專案打包成 exe 執行檔。
PyInstaller 是一個用於將 Python 程式碼打包成執行檔的 Python 套件,例如打包的檔案是 myscript.py,那麼 Windows 上 PyInstaller 生成的執行檔可能就會是 myscript.exe。PyInstaller 的優點是透過產生的執行檔,使用者可以在沒有安裝 Python 編譯器的環境中運行 Python 程式碼。
requirements.txt
中需要包含專案中使用到的所有 Python 函式庫。產生 requirements.txt
的指令是 pip freeze > requirement.txt
。pip install pyinstaller
。.ico
格式,如果沒有則略過此前置作業。確認安裝 PyInstaller 以後,先使用以下指令產生 .spec
檔案:
pyinstaller your_script.py
這裡的 your_script.py
是要打包的 Python 腳本名稱。執行此指令後,PyInstaller 會在當前的資料夾底下產生一個名稱為 your_script.spec
的檔案。
.spec
檔案是 PyInstaller 產生執行檔時的配置文件,它會記錄打包過程需要的所有參數和資源。當專案比較複雜時,可以透過修改 .spec
檔案定義 PyInstaller 打包的方式。
修改 .spec
檔案以後,可以透過以下指令產生正確的執行檔:
pyinstaller your_app_name.spec
PyInstaller 打包完成後,會在 dist
資料夾底下產生一個執行檔,可以點擊執行檔測試是否正常運行。另外,使用 PyInstaller 打包時,還會自動產生 build
資料夾,這個資料夾是 PyInstaller 用來儲存打包過程中間產物的地方。
假設針對 main.py
使用 pyinstaller main.py
指令以後,應該會產生類似下方的 main.spec
檔案:
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main',
)
假設現在的 Python 專案架構如下:
my_project/
│
├── main.py
├── assets/
│ └── icons/
│ └── icon.ico
├── classes/
│ └── (其他類別檔案)
├── utils/
│ └── (其他工具檔案)
└── requirements.txt
主要修改的地方是 main.spec
檔案上半部的 pathex=[]
跟 datas=[]
,需要依據專案的架構修改這兩個地方。例如:
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.py'],
pathex=['./'],
binaries=[],
datas=[
('assets/icons/icon.ico', 'assets/icons'),
('classes/', 'classes'),
('utils/', 'utils'),
('requirements.txt', '.')
],
# 省略後面內容...
)
pathex
是一個用來指定 Python 專案中要搜索的路徑列表。在這裡,['./']
表示當前資料夾,即包含 main.py
的資料夾,將被用於搜索路徑。這表示執行打包時,PyInstaller 會在當前的資料夾尋找模組和資源。
datas
是一個包含要打包進執行檔的資源檔案列表。這些檔案可以是圖片、聲音檔、文字檔案等,通常是執行檔運行所需的資源。每個項目都是一個元組 (tuple),格式為 (source, destination)
,其中:
例如 ('assets/icons/icon.ico', 'assets/icons')
表示將位於 assets/icons/icon.ico
的圖標檔案打包到最執行檔的 assets/icons/
資料夾下。('classes/', 'classes')
表示將整個 classes/
資料夾及其底下的全部內容打包到最終執行檔的同名資料夾下。
承接剛剛的例子,記得確保修改後的 .spec
檔案放在專案的根目錄中 (和 main.py 檔案在同一個地方),然後執行以下指令就會產生執行檔了:
pyinstaller main.spec
測試期間可能會重複執行 pyinstaller main.spec
指令,PyInstaller 在打包過程中會檢查指定的輸出資料夾是否已經存在且是否有內容。如果該資料夾已經存在,為了確保新產生的檔案不會與舊的檔案發生衝突,PyInstaller 會警告使用者確認是否要刪除該資料夾及其下所有內容。
如果遇到這個警告,有兩個回應的方式:
y
並按 Enter 鍵,這樣將刪除該資料夾及其下內容,並繼續打包過程。N
再按 Enter 鍵或直接按 Enter 鍵 (預設選擇為 N
),這樣將中止打包過程,並保留原有的輸出資料夾及其下內容。如果希望未來的打包過程中自動刪除輸出資料夾而不需要每次確認,可以使用 -y
或 --noconfirm
參數。例如:
pyinstaller main.spec -y
或是執行 PyInstaller 的指令前,先手動刪除輸出資料夾,避免出現警告。
.spec
檔案是 PyInstaller 的配置檔案,記錄打包過程需要的所有參數和資源。-y
或 --noconfirm
參數自動確認刪除。本篇文章同步發布於 如何使用 PyInstaller 將 Python 專案打包成 exe 執行檔?【Python 處理 Excel #28】