part17:Python打包和發布(zipapp,PyInstaller)



知識點:

  • 發布 Python 程序
  • 使用 zipapp 生成可執行的 Python 檔案包
  • 使用 zipapp 創建獨立應用
  • 安裝 PyInstaller 模塊
  • 使用 PyInstaller 生成 EXE 程序

經過一系列的開發、調試后得到的 Python 程序,接下來就是將這個程序發布出來。

兩個常用的發布工具:zipapp 和 PyInstaller。

zipapp 模塊生成可執行的 Python 檔案包,該檔案包包含目錄下所有的 Python 程序。如果使用 pip 工具先將 Python 程序所依賴的模塊下載到目錄下,那么就可以生成可獨立遠行的 Python 程序,只要目示機器上安裝有 Python 解釋器環境即可。

PyInstaller 工具更強大,可以直接將 Python 程序編譯成 Windows、Mac OS X 平台上的可執行程序,而無須這些機器上安裝 Python 環境。


一、使用 zipapp 模塊

zipapp 模塊可以將一個 Python 模塊(可能包含很多個源程序)打包生成一個 Python 應用,或者發布成一個 Windows 的可執行程序。


1、生成可執行的 Python 檔案包

zipapp 是一個可以直接運行的模塊,該模塊用於將單個 Python 文件或整個目錄下的所有文件打包成可執行的檔案包。命令行語法如下:

python -m zipapp source [options]

source 參數是要打包的 Python 源程序或目錄。如果source參數是目錄,則 zipapp 模塊會打包該文件夾中的所有 Python 文件。options 參數提供的選項如下:

  • -o <output>, --output=<output>:指定輸出檔案包的文件名,如果不指定,則使用默認文件名,默認是 source 參數值加上 .pyz 后綴。
  • -p<interpreter>, --python=<interpreter>:指定 Python 解釋器
  • -m <mainfn>, --main=<mainfn>:指定入口函數。該選項為 pkg.mod:fn 形式,其中 pkg.mod 是一個檔案包中的包或模塊,fn 是指定模塊中的函數。如果不指定該選項,則默認從模塊中的 __main__.py 文件開始執行。
  • -c, --compress:從 Python 3.7 開始支持該選項,指定檔案包進行壓縮來減小文件的大小,默認是不壓縮。
  • --info:在診斷時顯示檔案包中的解釋器。
  • -h, --help:顯示 zipapp 模塊的幫助信息。

zipapp 使用示例:創建一個 app 子目錄,該子目錄下可以有多個 Python 源文件,在該目錄下的第一個源文件是 say_hello.py,代碼如下:

def say_hello(name):
    return name + ",您好!"

第二個源文件是:app.py,用來使用 say_hello 模塊,代碼如下:

from sys import argv
from say_hello import *

def main():
    print('開始執行程序')
    for arg in argv[1:]:
        print(say_hello(arg))

回到 app 子目錄的上一級目錄,在命令行下執行下面的命令:

python -m zipapp app -o first.pyz -m "app:main"

執行上面命令后,app 子目錄下的所有 Python 源文件都會打包成一個檔案包,-o 選項指定的就是檔案包的文件名;-m 選項指定使用 app.py 模塊中的 main 函數作為程序入口。此時在當前目錄會生成一個 first.pyz 文件,可使用 Python 命令來運行該文件。示例如下:

> python first.pyz michael tom
開始執行程序
michael,您好!
tom,您好!

在執行打包命令時,如果不指定 -o 參數,則默認輸出的文件名是 source 參數值加上 .pyz后綴組成,例如:

python -m zipapp app -m "app:main"

此時會在當前目錄下生成 app.pyz 文件。


2、創建獨立應用

為了創建能夠獨立啟動的應用(自帶依賴模塊和包),需要執行兩步操作:

第1步:將應用依賴的模塊和包下載到應用目錄中。

第2步:使用 zipapp 將應用和依賴模塊一起打包成檔案包。

使用 zipapp 創建獨立應用示例:創建 dbapp 子目錄作為本應用的目錄,該目錄下的第一個 Python 源文件是 exec_select.py 文件,該源文件代碼如下:

import mysql.connector

# 將執行代碼封裝到 query_db 函數中
def query_db():
    # 第1步:連接 MySQL 數據庫,需要提供服務器IP地址、數據庫端口號、數據庫用戶名和密碼,以及數據庫名稱
    conn = mysql.connector.connect(user='michael', password='michael123', host='192.168.64.50',
                                   port='3508', database='python', use_unicode=True)
    conn.autocommit = True
    # 第2步:獲取游標
    c = conn.cursor()
    # 第3步:調用游標的 execute() 方法執行 select 查詢語句
    c.execute('select * from user_tb where user_id > %s', (4,))
    # 通過游標的 description 屬性獲取列字段信息
    for col in (c.description):
        print(col[0], end='\t')
    print('\n-------------------------------')
    # 直接使用 for 循環遍歷游標中的結果集
    for row in c:
        print(row)
        print(row[1] + '-->' + row[2])

    # 第4步:關閉游標
    c.close()
    # 第5步:關閉連接
    conn.close()

exec_select.py 文件的代碼主要是查詢 MySQL 數據庫中的數據,將主要的執行代碼都封裝到 query_db() 函數中。

在 dbapp 目錄下的第二個 Python 源文件是 __main__.py,這個文件作為程序入口,這樣在打包檔案時就不需要指定程序入口。該文件的代碼如下:

from exec_select import *

# 執行 query_db() 函數
query_db()

接下來按照下面3步將 dbapp 子目錄下的應用打包成獨立應用:

第1步:通過命令行工具在 dbapp 所在的目錄執行下面命令:

python -m pip install -r requirements.txt --target dbapp

上面的命令就是在使用 pip 模塊來安裝模塊,平時使用 pip 安裝模塊提示 pip 錯誤時,也可以使用 python -m pip install 來安裝模塊。--target 選項是將模塊安裝到指定目錄下,這里指定的是 dbapp 子目錄下。-r 選項指定要安裝哪些模塊,這里使用 requirements.txt 文件列出要安裝的模塊和包。

-r 選項后面可以直接指定要安裝的模塊和包,也可使用清單文件指定要安裝的模塊和包。

如果應用依賴的模塊較多,建議使用清單文件來列出所依賴的模塊。為了執行上面的命令,需要提前在當前目錄下准備好 requirements.txt 文件,該文件中的內容就一行:

mysql-connector-python

這個 requirements.txt 文件的每一行代表一個模塊,如果有多個依賴模塊,就在這個文件中添加多個模塊名的行。執行上面的命令,就開始安裝 mysql-connection-python 模塊。完成后可以在 dbapp 子目錄下看到大量有關 mysql-connection-python 模塊的文件。

第2步:如果 pip 在 dbapp 子目錄下生成了 .dist-info 目錄,可以刪除該目錄。

第3步:使用 zipapp 模塊執行打包操作,這次有了 __main__.py 文件,該文件會作為程序入口,因此在打包時不需要指定 -m 選項。打包命令如下:

python -m zipapp dbapp

此時會在當前目錄得到一個 dbapp.pyz 的檔案包,該檔案包約 20MB,因其包含了 myql-connector-python 模塊。

現在,只要目標機器上有合適的 Python 解釋器,即可運行該獨立應用。可先將本機上的 myql-connector-python 卸載進行測試。卸載命令是:

pip uninstall myql-connector-python

二、使用 PyInstaller 生成可執行程序


1、安裝 PyInstaller

PyInstaller 模塊需要自行安裝,安裝命令如下:

pip install pyinstaller

由於該模塊還依賴其他模塊,所以盡量不要采用離線包方式安裝。若成功安裝,可以在安裝界面看到類似下面的信息:

Successfully installed pyinstaller-3.6

其中的 3.6 之類的數字,代表 PyInstaller 的版本號。此時,在Python 安裝目錄下的 Script 目錄下也會增加一個 pyinstaller.exe 程序。使用該工具可將 Python 程序生成 EXE 程序。


2、生成可執行程序

PyInstaller 工具的命令語法如下:

pyinstaller 選項 Python源文件

不管這個 Python 應用是單文件的應用,壓是多文件的應用, 只要在使用 pyinstaller 命令時編譯作為程序入口的Python 程序即可。

為了進行示例,先將前面的 app.py 文件略做修改,將該文件改成可執行的 Python 程序。代碼如下:

from sys import argv
from say_hello import *

def main():
    print('開始執行程序')
    if len(argv[1:]) >= 1:
        for arg in argv[1:]:
            print(say_hello(arg))
    else:
        print(say_hello('michael'))

# 增加調用 main() 函數
if __name__ == '__main__':
    main()

接下來使用命令行工具進入到 app 目錄下,在該目錄下執行下面命令:

pyinstaller -F app.py

執行上面命令,可以看到詳細的生成過程。生成完成后,在app目錄下有一個 dist 目錄,在該目錄下有一個 app.exe 文件,這就是用 PyInstaller 工具生成的 EXE 程序。

在命令行窗口中進入到 dist 目錄,即可執行 app.exe 程序,示例如下:

...app\dist> .\app.exe tom jack
開始執行程序
tom,您好!
jack,您好!

需要注意的是,這個程序沒有圖形界面,如果雙擊 app.exe 來運行程序,會看到窗口一閃就消失,這樣也看不到程序輸出結果。

另外,pyinstaller 的 -F 選項是指定生成單獨的 EXE 文件,生成的文件在 dist 目錄下。在 Mac OS X 平台上生成的文件不帶 .exe 后綴。與 -F 選項對應的是 -D 選項(默認選項),該選項指定生成一個目錄(包含多個文件)來作為程序。

下面使用 -D 選項進行示例。先將 PyInstaller 工具在 app 目錄下生成的 build、dist 目錄刪除,將 app.spec 文件刪除。然后在app目錄使用下面命令生成 EXE 文件:

pyinstaller -D app.py

執行這個命令,同樣可以看到詳細的生成過程。生成完成后,在當前目錄下多出一個 dist 目錄,在 dist 目錄下有一個 app 子目錄,在該子目錄下包含了大量的 .dll 文件和 .pyz 文件,這些都是 app.exe 程序的支撐文件。在命令行窗口中運行 app.exe 程序,同樣可以正常輸出。

PyInstaller 不僅支持 -F、-D 選項,還支持其他選項,支持的常用選項如下表所示:

選項 作用
-h, --help 查看該模塊的幫助信息
-F, --onefile 產生單個的可執行文件
-D, --onedir 產生一個目錄(包含多個文件)作為可執行程序
-a, --ascii 不包含 Unicode 字符集支持
-d, --debug 產生 debug 版本的可執行文件
-w, --windowed, --noconsole 指定程序運行時不顯示命令行窗口(僅對 windows 有效)
-c, --nowindowed, --console 指定使用命令行窗口運行程序(僅對 windows 有效)
-o DIR, --out=DIR 指定 spec 文件的生成目錄。如果沒有指定,則默認使用當前目錄來生成 spec 文件
-p DIR, --path=DIR 設置 Python 導入模塊的路徑(和設置PYTHONPATH環境變量的作用相似),也可使用路徑分隔符(Windows用分號,Linux用冒號)來分隔多個路徑
-n NAME, --name=NAME 指定項目(產生的spec)名字。如果省略,那么第一個腳本的主文件名將作為 spec 的名字

PyInstaller 的選項不止上表這些,可以使用 -h 選項查看 PyInstaller 選項的詳細信息。

下面使用 PyInstaller 創建一個帶圖形用戶界面,可以訪問 MySQL 數據庫的應用程序。為此,新建一個 dbapp 目錄,將前面創建的 exec_select.py 文件和 __main__.py 拷貝到新建的 dbapp 目錄,在該目錄下執行下面的命令:

pyinstaller -F -w __main__.py

上面命令中,-F 選項生成單個可執行文件,-w 選項指定生成圖形用戶界面程序。現在在 dist 子目錄下找到 __main__.exe 文件,雙擊該文件即可運行該程序。


小結:

  • Python 的兩種打包工具:zipapp 和 PyInstaller。
  • zipapp 將文件打包成一個 .pyz 文件,該文件需要 Python 環境來執行。
  • PyInstaller 直接打包成可執行程序,該工具還是跨平台,使用也很方便。使用該工具打包的程序,可以分發到對應平台的目標機器上直接運行,無須在目標機器上安裝 Python 解釋器環境。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM