🍀從零開始:把 Python 轉成 Windows 可執行檔(.exe)的最完整新手教學|PyInstaller、Nuitka、離線安裝、簽章與常見錯誤排解

摘要(一句話就懂)

這篇文帶你從 安裝、打包、資源檔處理、錯誤排解、最佳化、到簽章與離線環境,手把手把 Python 程式變成能在任何 Windows 10/11 執行的 .exe


為什麼要把 Python 變成 .exe?

  • 讓對方的電腦不必安裝 Python也能執行

  • 方便發佈給使用者或客戶

  • 便於桌面捷徑、排程、自動啟動

  • 搭配簽章可降低防毒誤報、提升信任度


這篇文章適合誰?

  • 剛學會寫 Python、想把腳本給同事/客戶用

  • 做資料處理或小工具、希望一鍵打包

  • 公司有內網/無網環境需要部署

  • 想比較 PyInstaller vs Nuitka vs 其他工具 的人


你會用到的兩個主角

  • PyInstaller:最穩、最常用,對新手最友善

  • Nuitka:把 Python 編譯成 C,再生出執行檔;效能更好、可程式碼混淆比較強(需額外建置工具)

其他備用:cx_Freeze(結構清楚)、PyOxidizer(啟動快、較進階)



1. 安裝與環境準備(建議用虛擬環境)

這樣做能避免把東西裝亂、也比較好重現環境。


# 建立與啟用虛擬環境(以 Python 3.11 為例)
py -3.11 -m venv .venv .\.venv\Scripts\activate # 升級 pip 並裝 PyInstaller pip install --upgrade pip pip install pyinstaller

2. 第一個 .exe(命令最短版)

假設你的主程式叫 app.py

pyinstaller --onefile app.py

完成後,檔案會出現在 dist/app.exe

如果是 GUI(不要黑色主控台視窗)

pyinstaller --onefile -w app.py

3. 實用參數大全(常用就這幾個)

--name MyTool # 輸出 .exe 名稱 --icon path\to\app.ico # 指定圖示 --add-data "assets\*.png;assets" # 夾帶資源檔(Windows 用分號 ;) --hidden-import pkg.submodule # 動態匯入遺漏時補上 --noconfirm --clean # 覆蓋舊輸出 + 清暫存

範例(組合技)

pyinstaller --onefile -w ^ --name MyTool ^ --icon .\brand\app.ico ^ --add-data "assets\*.*;assets" ^ --hidden-import mypkg.plugins.reader ^ --noconfirm --clean app.py

4. 打包後如何正確存取資源檔(圖片、範本、設定)

打包成單檔 (--onefile) 後,執行時的資源暫存在特殊目錄。請用下列通用函式取得正確路徑:

# utils_paths.py(通用寫法) from pathlib import Path import sys def resource_path(relpath: str) -> Path: base = Path(getattr(sys, "_MEIPASS", Path(__file__).parent)) return base / relpath # 使用方式 logo = resource_path("assets/logo.png") config = resource_path("config/app.yaml")

5. 進階控制:使用 .spec 重新打包

第一次執行 PyInstaller 會產生 app.spec。你可編輯它,然後用它打包:

pyinstaller app.spec

最小可讀範例(節錄重點)

# app.spec(通用範例,無任何私密路徑) block_cipher = None a = Analysis( ['app.py'], pathex=[], datas=[('assets\\*.*', 'assets')], hiddenimports=['mypkg.plugins.reader'], excludes=['tests', 'tkinter'], ) exe = EXE( a.pure, a.scripts, a.binaries, a.zipfiles, a.datas, name='MyTool', icon='brand\\app.ico', console=False, # GUI 程式不顯示主控台 )

6. 常見框架快速攻略

某些框架(如 PyQt5 / PySide6 / pandas / matplotlib)會用到隱式資源。可以先嘗試:

pyinstaller --onefile -w app.py ^ --collect-all PySide6 ^ --collect-all pandas ^ --collect-all matplotlib

如果還是缺檔,改用 --add-data--collect-data 精準補上。


7. 錯誤排解(遇到這些,多半是這樣解)

  • Failed to execute script
    → 缺少隱式匯入或資源:加 --hidden-import--add-data

  • 圖示沒出現
    → 檢查 .ico 路徑是否正確;請用 .ico 而非 .png

  • 版本相容問題
    → 升級 pyinstaller;或改用較穩定的 Python 次版本

  • 防毒誤報
    → 優先用 --onedir 確認流程;上線前程式碼簽章(見下)

  • 到別的電腦跑不起來
    → 用「乾淨機」測試(Windows Sandbox/VM),檢查缺檔或權限


8. 檔案大小與啟動速度優化

  • --onedir(多檔)啟動較快、問題較好定位

  • 排除不需要的模組:--exclude-module

  • 安裝 UPX 後可嘗試壓縮:

    pyinstaller --onefile app.py --upx-dir C:\Tools\upx

    注意:UPX 偶爾會增加防毒誤報率,請自行權衡


9. 在公司環境:程式碼簽章(強烈建議)

有企業代碼簽章憑證時,請簽 .exe 以降低誤報、提升信任:

signtool sign /fd SHA256 /a ^ /tr http://timestamp.digicert.com ^ /td SHA256 dist\MyTool.exe

10. 一鍵打包:批次檔範本(可直接用)

把下面存成 build.bat,丟在專案根目錄即可用:

@echo off setlocal set PY=py -3.11 set VENV=.venv if not exist %VENV% ( %PY% -m venv %VENV% ) call %VENV%\Scripts\activate pip install -U pip pyinstaller pyinstaller --noconfirm --clean --onefile -w ^ --name MyTool ^ --icon brand\app.ico ^ --add-data "assets\*.*;assets" ^ --hidden-import mypkg.plugins.reader ^ src\app.py echo. echo Done! See .\dist\MyTool.exe endlocal

11. 無網/內網:離線安裝 PyInstaller

在可上網的機器先把安裝包抓好:

py -3.11 -m pip download pyinstaller --dest D:\offline_wheels

在內網機器離線安裝:

pip install --no-index --find-links=D:\offline_wheels pyinstaller

12. 替代方案速覽(什麼時候該換工具?)

Nuitka(效能與混淆需求)

優點:可把 Python 編譯成 C,執行效能更佳、可減少原始碼暴露
需要:MSVC Build Tools 或 MinGW

pip install nuitka python -m nuitka app.py ^ --onefile ^ --windows-disable-console ^ --enable-plugin=pyside6

cx_Freeze

  • 類似「setup.py」的專案型打包

  • 架構清晰,容易管控依賴

PyOxidizer

  • 超快啟動、單檔體驗佳

  • 學習曲線較陡,適合資深使用者


13. FAQ(最常被問到的 8 個問題)

Q1:我想要不要黑窗,它是 GUI 程式。
A:加 -w 或在 .specconsole=False

Q2:打包後資源路徑全壞光了?
A:請用上面的 resource_path() 通用函式存取。

Q3:pandas / matplotlib 打包後就掛?
A:加 --collect-all pandas --collect-all matplotlib,不行就精準補 --add-data

Q4:.exe 被防毒擋?
A:優先用 --onedir 減少誤判,正式發佈請簽章

Q5:可否跨平台(一次打包 Windows、macOS)?
A:不行。請在各平台各自打包。

Q6:.exe 很慢才啟動?
A:--onedir 通常較快;或試 UPX;或改用 Nuitka 提升效能。

Q7:.exe 太大?
A:排除不必要模組、移除測試檔、考慮 --onedir、必要時用 UPX。

Q8:如何自動化 CI/CD 打包?
A:把批次檔邏輯搬到 GitHub Actions / Jenkins,用自動簽章與產物上傳流程。


14. 發佈前檢查清單(Checklist)

  • 在「乾淨機器」跑過(Sandbox/VM)

  • 常用情境與錯誤流程都測過

  • 資源檔能正確讀取(resource_path

  • 有無需加 --hidden-import 的動態模組

  • 是否需要 --onedir 以便除錯

  • 是否完成代碼簽章

  • 使用者文件與版本號是否包含在 UI/關於視窗


結語

把 Python 打包成 .exe 一點也不神祕。PyInstaller 負責「穩定與好上手」,Nuitka 負責「效能與混淆」,兩者搭配能涵蓋 90% 以上的情境。照著本文一步步做,你就能在 Windows 上交付一個「可直接雙擊」的桌面小工具或企業內部工具。

留言

這個網誌中的熱門文章

🔍Vue.js 專案錯誤排查:解決 numericFields is not defined 與合併儲存格邏輯最佳化

🔎EF Core 連 Oracle 出現 ORA-00600 [kpp_concatq:2] 的完整排錯指南(含 EF Core ToString/CultureInfo 錯誤)

🛠【ASP.NET Core + Oracle】解決 ORA-00904 "FALSE": 無效的 ID 錯誤與資料欄位動態插入顯示問題