打包你的Python程式~PyInstaller基礎篇


介紹

  • 開發完的python工具,想發送給親朋好友使用,順便得到一些好棒棒的讚賞,這時候,你需要pyinstaller ,它可以幫你打包相關的python scriptlibrary,編譯出一個執行檔,提供使用者直接操作使用。
    • 罷特!仍有需要注意的地方,可參考底下的 小結1-跨平台問題

準備

  • 強烈建議使用python virtualenv來建構你的開發環境,系統乾淨之外,在執行pyinstaller打包時,可以避免打包不必要的library進來,減少執行檔的大小。

安裝

  • pip install pyinstaller
    • 個人推薦3.4版

基礎指令

  • 安裝完後,咱們先來看看他有哪些功能,開啟terminal 輸入pyinstaller --help ,簡單來說,就是pyinstaller + [功能指令] + [你的python script]

usage: pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME]                          
                   [--add-data <SRC;DEST or SRC:DEST>]                                     
                   [--add-binary <SRC;DEST or SRC:DEST>] [-p DIR]                          
                   [--hidden-import MODULENAME]                                            
                   [--additional-hooks-dir HOOKSPATH]                                      
                   [--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES]              
                   [--key KEY] [-d [{all,imports,bootloader,noarchive}]] [-s]              
                   [--noupx] [-c] [-w]                                                     
                   [-i <FILE.ico or FILE.exe,ID or FILE.icns>]                             
                   [--version-file FILE] [-m <FILE or XML>] [-r RESOURCE]                  
                   [--uac-admin] [--uac-uiaccess] [--win-private-assemblies]               
                   [--win-no-prefer-redirects]                                             
                   [--osx-bundle-identifier BUNDLE_IDENTIFIER]                             
                   [--runtime-tmpdir PATH] [--bootloader-ignore-signals]                   
                   [--distpath DIR] [--workpath WORKPATH] [-y]                             
                   [--upx-dir UPX_DIR] [-a] [--clean] [--log-level LEVEL]                  
                   scriptname [scriptname ...]  

...省略 ...

What to generate:
  -D, --onedir          Create a one-folder bundle containing an executable
                        (default)
  -F, --onefile         Create a one-file bundled executable.
  --specpath DIR        Folder to store the generated spec file (default:
                        current directory)
  -n NAME, --name NAME  Name to assign to the bundled app and spec file
                        (default: first script's basename)
  • 功能落落長,沒關係,我們先學會下面的基本指令,建立我們的自信心 :100:
縮寫指令 完整指令 說明
-D --onedir <font color='blue'>default:</font>將所有的東西打包到一個資料夾中
-F --onefile 將所有的東西打包到一個檔案中,ex: windows的exe檔
--specpath 輸出spec檔案到指定的資料夾
-n Name --name Name 打包的檔名

準備

  • 為了測試pyinstaller厲害的地方,咱們來安裝個GUI工具來測試 pip install PySide2,讓我們打包的程式,點兩下有個UI可以跑出來 :+1:
  • 開啟一個main.py貼上以下的程式碼:
import sys, os
from PySide2.QtWidgets import QApplication, QLabel
from PySide2.QtCore    import Qt

if __name__ == "__main__":

    # 下面指令是告訴QT,我要設計一個600(w)x100(h)大小的Label widget,上面顯示著`OKLA`
    app = QApplication(sys.argv)
    label = QLabel('OKLA')
    label.setFixedSize(300, 100)
    label.setAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
    label.show()

    sys.exit(app.exec_())
  • python main.py執行看看,會跑出如下的UI畫面

Test1: 快速打包(產出執行檔+相依的檔案)

  • 開啟terminal到資料夾下,並輸入以下指令pyinstaller main.py
    • 開始編譯
      -
  • 出現successfully編譯成功啦!

  • 檢查資料夾,會多出資料夾builddist,以及main.spec

檔案 說明
build資料夾 編譯執行檔過程的產物,先不須理會
dist 資料夾 :accept: 編譯的結果,也就是我們要的執行檔
main.spec 其實是根據使用者針對pyinstaller有使用到的功能,整理成spec檔,進階的方式也可以進去裡面修改,會在下一次介紹。

  • 開啟dist/main資料夾,你會發現到一個main執行檔

Test2: 完整打包(打包出一個檔案)

  • 為了避免編譯出錯,我們先將剛剛的distbuild資料夾砍掉,在輸入以下指令,並將他命名為justRunMe

    • pyinstaller -F -n justRunMe main.py, 打包比較久,先吃塊蛋糕:cake:
  • 編譯完後,打開dist資料夾,剛剛的程式都被打包成一個檔案,並命名為justRunMe,點兩下...見證奇蹟的Magic出現了

小結

  • pyinstaller對於python開發者是個方便打包的軟體,這幾個指令足夠應付一般的使用。
  • 不過,在windows及Linux(Ubuntu18.04)有個小地方要注意:

1. 跨平台的問題:

Windows:

  • 打包的東西能夠順利的拷貝到其他的Windows平台上執行,完全沒問題。

Linux(於Ubuntu18.04測試):

  • 如果你打包的系統是python3.6,但運行於python3.5或以下版本的電腦,系統將無法順利運行,原因如下,簡單來說 GLIBC可以往後兼容,但不能往前,所以使用上要注意

2. 編譯後的檔案大小

  • 這篇提到,不同的python版本,編譯出來的檔案大小也會不同。
  • 根據我的測試,不同的pyInstaller版本,打包的結果也會有所不同,推測應該是掃描相依lib時有所不同

  • 我實際測試的結果:
    • pyInstaller 3.4 => 打包後60幾mb
    • pyInstaller>=3.5 => 打包後120幾mb :

Reference

#Python #pyinstaller






留言討論