Python 的 zipapp:構(gòu)建可執(zhí)行的 Zip 應(yīng)用程序
目錄
Python Zip 應(yīng)用程序入門(mén)
什么是 Python Zip 應(yīng)用程序?
為什么要使用 Python Zip 應(yīng)用程序?
如何構(gòu)建 Python Zip 應(yīng)用程序?
設(shè)置 Python Zip 應(yīng)用程序
使用 zipapp 構(gòu)建 Python Zip 應(yīng)用程序
從命令行使用 zipapp
從 Python 代碼使用 zipapp
運(yùn)行 Python Zip 應(yīng)用程序
使用 zipapp 創(chuàng)建一個(gè)獨(dú)立的 Python Zip 應(yīng)用程序
手動(dòng)創(chuàng)建 Python Zip 應(yīng)用程序
使用 Python 的 zipfile
使用 Unix 命令行工具
使用第三方工具創(chuàng)建 Python 應(yīng)用程序
結(jié)論
Python Zip 應(yīng)用程序是一個(gè)快速而酷的選項(xiàng),您可以將可執(zhí)行應(yīng)用程序捆綁并分發(fā)到一個(gè)可立即運(yùn)行的文件中,這將使您的最終用戶體驗(yàn)更加愉快。如果您想了解 Python 應(yīng)用程序以及如何使用zipapp標(biāo)準(zhǔn)庫(kù)創(chuàng)建它們,那么本教程適合您。
您將能夠創(chuàng)建 Python Zip 應(yīng)用程序,作為將您的軟件產(chǎn)品分發(fā)給最終用戶和客戶的一種快速且可訪問(wèn)的方式。
在本教程中,您將學(xué)習(xí):
什么是Python的應(yīng)用郵編是
Zip 應(yīng)用程序如何在內(nèi)部工作
如何構(gòu)建Python Zip 應(yīng)用程序zipapp
什么是獨(dú)立的 Python Zip 應(yīng)用程序以及如何創(chuàng)建它們
如何使用命令行工具手動(dòng)創(chuàng)建 Python Zip 應(yīng)用程序
您還將了解一些用于創(chuàng)建 Zip 應(yīng)用程序的第三方庫(kù),這些庫(kù)克服了zipapp.
為了更好地理解本教程,您需要了解如何構(gòu)建 Python 應(yīng)用程序布局、運(yùn)行 Python 腳本、構(gòu)建 Python 包、使用Python 虛擬環(huán)境以及使用pip.?您還需要習(xí)慣使用命令行或終端。
Python Zip 應(yīng)用程序入門(mén)
Python 生態(tài)系統(tǒng)中最具挑戰(zhàn)性的問(wèn)題之一是找到一種有效的方法來(lái)分發(fā)可執(zhí)行應(yīng)用程序,例如圖形用戶界面 (GUI)和命令行界面 (CLI)程序。
編譯的編程語(yǔ)言,如C、C++和Go,可以生成可執(zhí)行文件,您可以直接在不同的操作系統(tǒng)和體系結(jié)構(gòu)上運(yùn)行。這種能力使您可以輕松地向最終用戶分發(fā)軟件。
然而,Python 不是這樣工作的。Python 是一種解釋型語(yǔ)言,這意味著您需要一個(gè)合適的 Python 解釋器來(lái)運(yùn)行您的應(yīng)用程序。沒(méi)有直接的方法可以生成不需要解釋器運(yùn)行的獨(dú)立可執(zhí)行文件。
有許多解決方案旨在解決這個(gè)問(wèn)題。您會(huì)找到諸如PyInstaller、py2exe、py2app、Nuitka等工具。這些工具允許您創(chuàng)建可以分發(fā)給最終用戶的獨(dú)立可執(zhí)行應(yīng)用程序。但是,設(shè)置這些工具可能是一個(gè)復(fù)雜且具有挑戰(zhàn)性的過(guò)程。
有時(shí)您不需要那種額外的復(fù)雜性。您只需要從腳本或小程序構(gòu)建一個(gè)可執(zhí)行的應(yīng)用程序,即可快速將其分發(fā)給最終用戶。如果您的應(yīng)用程序足夠小并且使用純 Python 代碼,那么您可以使用Python Zip 應(yīng)用程序提供良好的服務(wù)。
什么是 Python Zip 應(yīng)用程序?
PEP 441 – 改進(jìn) Python ZIP 應(yīng)用程序支持使Python Zip 應(yīng)用程序的思想、術(shù)語(yǔ)和規(guī)范正式化。這種類型的應(yīng)用程序由一個(gè)使用ZIP 文件格式的文件組成,并包含 Python 可以作為程序執(zhí)行的代碼。這些應(yīng)用程序依賴于 Python 從 ZIP 文件中運(yùn)行代碼的能力,這些 ZIP 文件__main__.py的根有一個(gè)模塊,作為入口點(diǎn)腳本工作。
自2.6 和 3.0版本以來(lái),Python 已經(jīng)能夠從 ZIP 文件運(yùn)行腳本。實(shí)現(xiàn)這一目標(biāo)的步驟非常簡(jiǎn)單。您只需要一個(gè) ZIP 文件__main__.py,其根目錄下有一個(gè)模塊。然后,您可以將該文件傳遞給 Python,Python 將其添加到程序中sys.path并__main__.py作為程序執(zhí)行。將應(yīng)用程序的存檔放入sys.path允許您通過(guò) Python 的導(dǎo)入系統(tǒng)訪問(wèn)其代碼。
作為所有工作原理的快速示例,假設(shè)您在類 Unix操作系統(tǒng)上,例如 Linux 或 macOS,并運(yùn)行以下命令:
$ echo 'print("Hello, World!")' > __main__.py $ zip hello.zip __main__.py adding: __main__.py (stored 0%) $ python ./hello.zip Hello, World!
您可以使用該echo命令創(chuàng)建一個(gè)__main__.py包含代碼的文件print("Hello, World!")。然后使用該zip命令歸檔__main__.py到hello.zip.?完成后,您可以hello.zip通過(guò)將文件名作為參數(shù)傳遞給python命令來(lái)作為程序運(yùn)行。
為了總結(jié) Python Zip 應(yīng)用程序的內(nèi)部結(jié)構(gòu),您需要一種方法來(lái)告訴操作系統(tǒng)如何執(zhí)行它們。ZIP 文件格式允許您在 ZIP 存檔的開(kāi)頭添加任意數(shù)據(jù)。Python Zip 應(yīng)用程序利用該功能在應(yīng)用程序的存檔中包含標(biāo)準(zhǔn)的Unix shebang行:
#!/usr/bin/env python3
在 Unix 系統(tǒng)上,這一行告訴操作系統(tǒng)使用哪個(gè)程序來(lái)執(zhí)行手頭的文件,以便您可以直接運(yùn)行該文件而無(wú)需python命令。在 Windows 系統(tǒng)上,Python 啟動(dòng)器正確理解 shebang 行并為您運(yùn)行 Zip 應(yīng)用程序。
即使使用 shebang 行,您始終可以通過(guò)將應(yīng)用程序的文件名作為參數(shù)傳遞給python命令來(lái)執(zhí)行 Python Zip 應(yīng)用程序。
總之,要構(gòu)建 Python Zip 應(yīng)用程序,您需要:
使用標(biāo)準(zhǔn) ZIP 文件格式并在其根目錄包含一個(gè)__main__.py模塊的存檔
一個(gè)可選的shebang 行,指定合適的Python 解釋器來(lái)運(yùn)行應(yīng)用程序
除了__main__.py模塊之外,應(yīng)用程序的 ZIP 文件還可以包含 Python模塊和包以及任何其他任意文件。但是,只有.py、.pyc和.pyo文件可通過(guò)導(dǎo)入系統(tǒng)直接使用。換句話說(shuō),您可以在應(yīng)用程序文件中打包.pyd、.so和.dll文件,但除非將它們解壓縮到文件系統(tǒng)中,否則將無(wú)法使用它們。
注:從執(zhí)行代碼的可能性.pyd,.so以及.dll文件存儲(chǔ)在一個(gè)ZIP文件是操作系統(tǒng)的限制。這種限制使得很難創(chuàng)建zip應(yīng)用程序,船舶和使用.pyd,.so以及.dll文件。
Python 生態(tài)系統(tǒng)充滿了用 C 或 C++ 編寫(xiě)的有用的庫(kù)和工具,以保證速度和效率。即使您可以將這些庫(kù)中的任何一個(gè)捆綁到 Zip 應(yīng)用程序的存檔中,您也無(wú)法直接從那里使用它們。您需要將庫(kù)解壓縮到您的文件系統(tǒng)中,然后從該新位置訪問(wèn)其組件。
PEP 441 提出.pyz并.pyzw作為Python Zip 應(yīng)用程序的文件擴(kuò)展名。的.pyz分機(jī)識(shí)別控制臺(tái)或命令行應(yīng)用程序,而.pyzw擴(kuò)展名是指窗或GUI應(yīng)用程序。
在 Unix 系統(tǒng)上,.pyz如果您更喜歡 CLI 應(yīng)用程序的簡(jiǎn)單命令名稱,則可以刪除擴(kuò)展名。在 Windows 上,.pyz和.pyzw文件是可執(zhí)行文件,因?yàn)?Python 解釋器將它們注冊(cè)為可執(zhí)行文件。
為什么要使用 Python Zip 應(yīng)用程序?
假設(shè)您有一個(gè)程序,您的團(tuán)隊(duì)在其內(nèi)部工作流程中經(jīng)常使用該程序。該程序已經(jīng)從單個(gè)文件腳本發(fā)展成為具有多個(gè)包、模塊和文件的成熟應(yīng)用程序。
此時(shí),一些團(tuán)隊(duì)成員難以安裝和設(shè)置每個(gè)新版本。他們不斷要求您提供一種更快、更簡(jiǎn)單的方法來(lái)設(shè)置和運(yùn)行程序。在這種情況下,您應(yīng)該考慮創(chuàng)建一個(gè) Python Zip 應(yīng)用程序,將您的程序捆綁到一個(gè)文件中,并將其作為一個(gè)隨時(shí)可用的應(yīng)用程序分發(fā)給您的同事。
Python Zip 應(yīng)用程序是發(fā)布必須作為單個(gè)可執(zhí)行文件分發(fā)的軟件的絕佳選擇。這也是使用非正式渠道分發(fā)軟件的便捷方式,例如通過(guò)計(jì)算機(jī)網(wǎng)絡(luò)發(fā)送軟件或?qū)⑵渫泄茉?FTP 服務(wù)器上。
Python Zip 應(yīng)用程序是一種方便快捷的方法,可以將 Python 應(yīng)用程序打包和分發(fā)為即用型格式,可以讓您的最終用戶的生活更加愉快。
如何構(gòu)建 Python Zip 應(yīng)用程序?
正如您已經(jīng)了解到的,Python Zip 應(yīng)用程序由一個(gè)包含__main__.py模塊的標(biāo)準(zhǔn) ZIP 文件組成,該模塊用作應(yīng)用程序的入口點(diǎn)。當(dāng)您運(yùn)行應(yīng)用程序時(shí),Python 會(huì)自動(dòng)將其容器(ZIP 文件本身)添加到其中,sys.path以便__main__.py可以從塑造應(yīng)用程序的模塊和包中導(dǎo)入對(duì)象。
要構(gòu)建 Python Zip 應(yīng)用程序,您可以運(yùn)行以下常規(guī)步驟:
創(chuàng)建包含__main__.py模塊的應(yīng)用程序源目錄。
壓縮應(yīng)用程序的源目錄。
添加一個(gè)可選的 Unix shebang 行來(lái)定義用于運(yùn)行應(yīng)用程序的解釋器。
使應(yīng)用程序的 ZIP 文件可執(zhí)行。此步驟僅適用于類 Unix 操作系統(tǒng)。
這些步驟非常簡(jiǎn)單且可以快速運(yùn)行。有了它們,如果您擁有所需的工具和知識(shí),就可以在幾分鐘內(nèi)手動(dòng)構(gòu)建 Python Zip 應(yīng)用程序。但是,Python標(biāo)準(zhǔn)庫(kù)為您提供了更方便、更快捷的解決方案。
PEP 441 提議添加一個(gè)新模塊,稱為zipapp標(biāo)準(zhǔn)庫(kù)。這個(gè)模塊促進(jìn)了 Zip 應(yīng)用程序的創(chuàng)建,它從Python 3.5開(kāi)始可用。
在本教程中,您將專注于使用zipapp.?但是,您還將學(xué)習(xí)如何使用不同的工具手動(dòng)運(yùn)行整個(gè)系列的步驟。這些額外的知識(shí)可以幫助您更深入地了解創(chuàng)建 Python Zip 應(yīng)用程序的整個(gè)過(guò)程。如果您使用低于 3.5 的 Python 版本,它也會(huì)有所幫助。
設(shè)置 Python Zip 應(yīng)用程序
到目前為止,您已經(jīng)了解了什么是 Python Zip 應(yīng)用程序、如何構(gòu)建它們、為什么使用它們以及在創(chuàng)建它們時(shí)需要遵循哪些步驟。您已準(zhǔn)備好開(kāi)始構(gòu)建自己的。不過(guò),首先,您需要有一個(gè)可用于 Python Zip 應(yīng)用程序的功能性應(yīng)用程序或腳本。
在本教程中,您將使用一個(gè)名為 的示例應(yīng)用程序reader,它是一個(gè)最小的Web 訂閱源閱讀器,可以從Real Python?feed讀取最新的文章和資源。
接下來(lái),您應(yīng)該將 的存儲(chǔ)庫(kù)克隆reader到本地計(jì)算機(jī)中。在您選擇的工作目錄中打開(kāi)命令行并運(yùn)行以下命令:
$ git clone https://github.com/realpython/reader.git
此命令將reader存儲(chǔ)庫(kù)的完整內(nèi)容下載到reader/當(dāng)前目錄中的文件夾中。
注:查看介紹Git和GitHub上的Python開(kāi)發(fā)者,如果你不熟悉的Git和GitHub上。
克隆存儲(chǔ)庫(kù)后,您需要安裝應(yīng)用程序的依賴項(xiàng)。首先,您應(yīng)該創(chuàng)建一個(gè) Python虛擬環(huán)境。繼續(xù)并運(yùn)行以下命令:
$ cd reader/ $ python3 -m venv ./venv $ source venv/bin/activate
這些命令在reader/目錄中創(chuàng)建并激活一個(gè)新的 Python 虛擬環(huán)境,該目錄是reader項(xiàng)目的根目錄。
注意:要在 Windows 上創(chuàng)建和激活虛擬環(huán)境,您可以運(yùn)行以下命令:
C:\> python -m venv venv C:\> venv\Scripts\activate.bat
如果您在不同的平臺(tái)上,那么您可能需要查看 Python 關(guān)于創(chuàng)建虛擬環(huán)境的官方文檔。
現(xiàn)在您可以安裝reader使用的依賴項(xiàng)pip:
(venv) $ python -m pip install feedparser html2text importlib_resources
運(yùn)行上面的命令將在活動(dòng)的 Python 虛擬環(huán)境中安裝所有應(yīng)用程序的依賴項(xiàng)。
注意:自 Python 3.7 起,importlib_resources在標(biāo)準(zhǔn)庫(kù)中作為importlib.resources.?因此,如果您使用的是大于或等于 3.7 的版本,則無(wú)需安裝此庫(kù)。只需在__init__.py定義reader包的文件中更改相應(yīng)的導(dǎo)入即可。
下面是一個(gè)reader用于從Real Python獲取最新文章、課程、播客集和其他學(xué)習(xí)資源列表的示例:
(venv) $ python -m reader The latest tutorials from Real Python (https://realpython.com/) 0 The Django Template Language: Tags and Filters 1 Pass by Reference in Python: Best Practices 2 Using the "and" Boolean Operator in Python ...
由于reader在提要中列出了 30 個(gè)最新的學(xué)習(xí)資源,因此此輸出對(duì)您來(lái)說(shuō)會(huì)有所不同。每個(gè)學(xué)習(xí)資源都有一個(gè) ID 號(hào)。要從這些學(xué)習(xí)資源中獲取一項(xiàng)的內(nèi)容,您可以將相應(yīng)的 ID 號(hào)作為命令行參數(shù)傳遞給reader:
(venv) $ python -m reader 2 Using the "and" Boolean Operator in Python Python has three Boolean operators, or **logical operators** : `and`, `or`, and `not`. You can use them to check if certain conditions are met before deciding the execution path your programs will follow. In this tutorial, you'll learn about the `and` operator and how to use it in your code. ...
此命令使用Markdown文本格式將文章Using the “and” Boolean Operator in Python 的部分內(nèi)容打印到屏幕上。您可以通過(guò)更改 ID 號(hào)來(lái)閱讀任何可用的內(nèi)容。
注意:reader工作原理的詳細(xì)信息與本教程無(wú)關(guān)。如果您對(duì)實(shí)現(xiàn)感興趣,請(qǐng)查看如何將開(kāi)源 Python 包發(fā)布到 PyPI。特別是,您可以閱讀名為A Quick Look at the Code 的部分。
要從reader存儲(chǔ)庫(kù)創(chuàng)建 Zip 應(yīng)用程序,您將主要使用該reader/文件夾。該文件夾具有以下結(jié)構(gòu):
reader/ | ├── config.cfg ├── feed.py ├── __init__.py ├── __main__.py └── viewer.py
從reader/目錄中要注意的最重要的事實(shí)是它包含一個(gè)__main__.py文件。該文件使您能夠python -m reader像以前一樣使用命令執(zhí)行包。
擁有__main__.py文件提供了創(chuàng)建 Python Zip 應(yīng)用程序所需的入口點(diǎn)腳本。在此示例中,__main__.py文件位于reader包內(nèi)。如果您使用此目錄結(jié)構(gòu)創(chuàng)建 Zip 應(yīng)用程序,則您的應(yīng)用程序?qū)o(wú)法運(yùn)行,因?yàn)開(kāi)_main__.py無(wú)法從.zip 文件導(dǎo)入對(duì)象reader。
要解決此問(wèn)題,請(qǐng)將reader包復(fù)制到名為的外部目錄realpython/并將__main__.py文件放在其根目錄下。然后刪除__pycache__/運(yùn)行結(jié)果的文件夾,python -m reader您之前這樣做過(guò)。您應(yīng)該最終得到以下目錄結(jié)構(gòu):
realpython/ │ ├── reader/ │ ├── __init__.py │ ├── config.cfg │ ├── feed.py │ └── viewer.py │ └── __main__.py
有了這個(gè)新的目錄結(jié)構(gòu),您就可以使用zipapp.?這就是您將在下一節(jié)中執(zhí)行的操作。
使用以下命令構(gòu)建 Python Zip 應(yīng)用程序?zipapp
要?jiǎng)?chuàng)建您的第一個(gè) Python Zip 應(yīng)用程序,您將使用zipapp.?該模塊實(shí)現(xiàn)了一個(gè)用戶友好的命令行界面,該界面為您提供了使用單個(gè)命令構(gòu)建成熟的 Zip 應(yīng)用程序所需的選項(xiàng)。您還可以zipapp通過(guò)模塊的Python API從您的代碼中使用,該API主要由單個(gè)函數(shù)組成。
在以下兩節(jié)中,您將了解使用 .zip 構(gòu)建 Zip 應(yīng)用程序的兩種方法zipapp。
zipapp從命令行使用
的命令行界面zipapp簡(jiǎn)化了將 Python 應(yīng)用程序打包成 ZIP 文件的過(guò)程。在內(nèi)部,zipapp通過(guò)運(yùn)行您之前學(xué)習(xí)的步驟從源代碼創(chuàng)建一個(gè) Zip 應(yīng)用程序。
要從命令行運(yùn)行zipapp,您應(yīng)該使用以下命令語(yǔ)法:
$ python -m zipapp
如果source是目錄,則此命令將從該目錄的內(nèi)容創(chuàng)建一個(gè) Zip 應(yīng)用程序。如果source是文件,則該文件應(yīng)該是包含應(yīng)用程序代碼的 ZIP 文件。然后將輸入 ZIP 文件的內(nèi)容復(fù)制到目標(biāo)應(yīng)用程序存檔。
以下是zipapp接受的命令行選項(xiàng)的摘要:
此表提供了zipapp.?有關(guān)每個(gè)選項(xiàng)的特定行為的更多詳細(xì)信息,請(qǐng)查看官方文檔。
現(xiàn)在您已經(jīng)了解了zipapp從命令行使用的基礎(chǔ)知識(shí),是時(shí)候構(gòu)建readerZip 應(yīng)用程序了。返回終端窗口并運(yùn)行以下命令:
(venv) $ python -m zipapp realpython/ \ -o realpython.pyz \ -p "/usr/bin/env python3"
在此命令中,您將realpython/目錄設(shè)置為 Zip 應(yīng)用程序的源。使用該-o選項(xiàng),您可以為應(yīng)用程序的存檔提供一個(gè)名稱realpython.pyz.?最后,該-p選項(xiàng)允許您設(shè)置zipapp將用于構(gòu)建 shebang 行的解釋器。
就是這樣!現(xiàn)在您將realpython.pyz在當(dāng)前目錄中有一個(gè)文件。稍后您將學(xué)習(xí)如何執(zhí)行該文件。
為了展示-m和 的--main命令行選項(xiàng)zipapp,假設(shè)您決定在將文件移回包的同時(shí)更改reader項(xiàng)目布局并重命名__main__.py為。繼續(xù)創(chuàng)建目錄的副本并進(jìn)行建議的更改。之后,副本應(yīng)如下所示:cli.pyreaderrealpython/realpython/
realpython_copy/ │ └── reader/ ├── __init__.py ├── cli.py ├── config.cfg ├── feed.py └── viewer.py
目前,您的應(yīng)用程序的源目錄沒(méi)有__main__.py模塊。的-m命令行選項(xiàng)zipapp允許您自動(dòng)生成它:
$ python -m zipapp realpython_copy/ \ -o realpython.pyz \ -p "/usr/bin/env python3" \ -m "reader.cli:main"
此命令將-m選項(xiàng) with"reader.cli:main"作為參數(shù)。此輸入值z(mì)ipapp表明 Zip 應(yīng)用程序可調(diào)用的入口點(diǎn)main()來(lái)自包中的cli.py模塊reader。
生成的__main__.py文件具有以下內(nèi)容:
# -*- coding: utf-8 -*- import reader.cli reader.cli.main()
__main__.py然后將此文件與您的應(yīng)用程序源一起打包到一個(gè)名為 .zip 的 ZIP 存檔中realpython.pyz。
使用zipappPython代碼
Pythonzipapp還有一個(gè)應(yīng)用程序編程接口 (API),您可以從 Python 代碼中使用它。這個(gè) API 主要由一個(gè)名為create_archive().?使用此功能,您可以快速創(chuàng)建 Python Zip 應(yīng)用程序:
>>>
>>> import zipapp >>> zipapp.create_archive( ... source="realpython/", ... target="realpython.pyz", ... interpreter="/usr/bin/env python3", ... )
此調(diào)用create_archive()采用第一個(gè)參數(shù)source,該參數(shù)表示 Zip 應(yīng)用程序的來(lái)源。第二個(gè)參數(shù) ,target保存應(yīng)用程序存檔的文件名。最后,interpreter保存解釋器以構(gòu)建并作為 shebang 行添加到應(yīng)用程序的 ZIP 存檔中。
以下是create_archive()可以采用的參數(shù)的摘要:
source?可以取以下對(duì)象:
現(xiàn)有源目錄的基于字符串的路徑
甲路徑狀物體參照現(xiàn)有的源目錄
現(xiàn)有 Zip 應(yīng)用程序存檔的基于字符串的路徑
引用現(xiàn)有 Zip 應(yīng)用程序存檔的類似路徑的對(duì)象
一個(gè)類文件對(duì)象為讀取而打開(kāi)指向現(xiàn)有的壓縮應(yīng)用程序歸檔
target?接受以下對(duì)象:
目標(biāo) Zip 應(yīng)用程序文件的基于字符串的路徑
目標(biāo) Zip 應(yīng)用程序文件的類似路徑的對(duì)象
interpreter指定一個(gè) Python 解釋器,它在結(jié)果應(yīng)用程序存檔的開(kāi)頭寫(xiě)為 shebang 行。省略這個(gè)參數(shù)會(huì)導(dǎo)致沒(méi)有shebang 行,也沒(méi)有應(yīng)用程序的執(zhí)行權(quán)限。
main指定zipapp將用作目標(biāo)存檔入口點(diǎn)的可調(diào)用文件的名稱。main當(dāng)您沒(méi)有__main__.py文件時(shí),您提供一個(gè)值。
filter如果應(yīng)將源目錄中的給定文件添加到最終的 Zip 應(yīng)用程序文件,則采用布爾值函數(shù)應(yīng)返回True該函數(shù)。
compressed?接受一個(gè)布爾值,該值決定是否要壓縮源文件。
這些參數(shù)中的大多數(shù)在zipapp.?上面的例子只使用了前三個(gè)參數(shù)。根據(jù)您的特定需求,您也可以使用其他參數(shù)。
運(yùn)行 Python Zip 應(yīng)用程序
到目前為止,您已經(jīng)學(xué)習(xí)了如何使用zipapp命令行和 Python 代碼創(chuàng)建 Python Zip 應(yīng)用程序。現(xiàn)在是時(shí)候運(yùn)行您的realpython.pyz應(yīng)用程序以確保其正常工作。
如果您使用的是類 Unix 系統(tǒng),那么您可以通過(guò)執(zhí)行以下命令來(lái)運(yùn)行您的應(yīng)用程序:
(venv) $ ./realpython.pyz The latest tutorials from Real Python (https://realpython.com/) 0 The Django Template Language: Tags and Filters 1 Pass by Reference in Python: Best Practices 2 Using the "and" Boolean Operator in Python ...
涼爽的!有用!現(xiàn)在您擁有一個(gè)可以快速與朋友和同事共享的應(yīng)用程序文件。
您不再需要調(diào)用 Python 來(lái)從命令行運(yùn)行應(yīng)用程序。由于您的 Zip 應(yīng)用程序存檔在開(kāi)頭有一個(gè) shebang 行,因此操作系統(tǒng)將自動(dòng)使用您的活動(dòng) Python 解釋器來(lái)運(yùn)行目標(biāo)存檔的內(nèi)容。
注意:要運(yùn)行您的應(yīng)用程序,您需要在 Python 環(huán)境中安裝所有必需的依賴項(xiàng)。否則,你會(huì)得到一個(gè)ImportError.
如果您使用的是 Windows,那么您的 Python 安裝應(yīng)該已經(jīng)注冊(cè).pyz和.pyzw文件并且應(yīng)該能夠運(yùn)行它們:
C:\> .\realpython.pyz The latest tutorials from Real Python (https://realpython.com/) 0 The Django Template Language: Tags and Filters 1 Pass by Reference in Python: Best Practices 2 Using the "and" Boolean Operator in Python ...
reader您在本教程中使用的應(yīng)用程序有一個(gè)命令行界面,因此從命令行或終端窗口運(yùn)行它是有意義的。但是,如果您有一個(gè) GUI 應(yīng)用程序,那么您將能夠從您最喜歡的文件管理器中運(yùn)行它,就像您通常運(yùn)行可執(zhí)行應(yīng)用程序一樣。
同樣,您可以通過(guò)使用應(yīng)用程序的文件名作為參數(shù)調(diào)用適當(dāng)?shù)?Python 解釋器來(lái)執(zhí)行任何 Zip 應(yīng)用程序:
$ python3 realpython.pyz The latest tutorials from Real Python (https://realpython.com/) 0 The Django Template Language: Tags and Filters 1 Pass by Reference in Python: Best Practices 2 Using the "and" Boolean Operator in Python ...
在本例中,您使用系統(tǒng) Python 3.x 安裝來(lái)運(yùn)行realpython.pyz.?如果您的系統(tǒng)上有許多 Python 版本,那么您可能需要更具體并使用類似python3.9 realpython.pyz.
請(qǐng)注意,無(wú)論您使用什么解釋器,都需要安裝應(yīng)用程序的依賴項(xiàng)。否則,您的應(yīng)用程序?qū)⑹ 2粷M意的依賴是 Python Zip 應(yīng)用程序的常見(jiàn)問(wèn)題。要解決這種煩人的情況,您可以創(chuàng)建一個(gè)獨(dú)立的應(yīng)用程序,這是下一節(jié)的主題。
創(chuàng)建一個(gè)獨(dú)立的 Python Zip 應(yīng)用程序?zipapp
您還可以使用zipapp創(chuàng)建自包含或獨(dú)立的 Python Zip 應(yīng)用程序。這種類型的應(yīng)用程序?qū)⑵渌幸蕾図?xiàng)捆綁到應(yīng)用程序的 ZIP 文件中。這樣,您的最終用戶只需要一個(gè)合適的 Python 解釋器來(lái)運(yùn)行應(yīng)用程序。他們不需要擔(dān)心依賴關(guān)系。
要?jiǎng)?chuàng)建獨(dú)立的 Python Zip 應(yīng)用程序,首先需要使用pip.?繼續(xù)并realpython/使用名稱創(chuàng)建目錄的副本realpython_sa/。然后運(yùn)行以下命令來(lái)安裝應(yīng)用程序的依賴項(xiàng):
(venv) $ python -m pip install feedparser html2text importlib_resources \ --target realpython_sa/
此命令安裝與選項(xiàng)一起reader使用的所有依賴項(xiàng)。的文檔說(shuō)此選項(xiàng)允許您將軟件包安裝到目標(biāo)目錄中。在此示例中,該目錄必須是您的應(yīng)用程序的源目錄.pip install--targetpiprealpython_sa/
注意:如果您的應(yīng)用程序有requirements.txt文件,那么您可以使用快捷方式安裝依賴項(xiàng)。
您可以改為運(yùn)行以下命令:
(venv) $ python -m pip install \ -r requirements.txt \ --target app_directory/
使用此命令,您可以將應(yīng)用程序requirements.txt文件中列出的所有依賴項(xiàng)安裝到該app_directory/文件夾中。
安裝readerinto的依賴項(xiàng)后realpython_sa/,您可以選擇刪除創(chuàng)建的*.dist-info目錄pip。這些目錄包含幾個(gè)帶有元數(shù)據(jù)的文件,pip用于管理相應(yīng)的包。由于您不再需要該信息,因此可以將其刪除。
該過(guò)程的最后一步是zipapp像往常一樣使用以下命令構(gòu)建 Zip 應(yīng)用程序:
(venv) $ python -m zipapp realpython_sa/ \ -p "/usr/bin/env python3" \ -o realpython_sa.pyz \ -c
此命令生成一個(gè)獨(dú)立的 Python Zip 應(yīng)用程序realpython_sa.pyz。要運(yùn)行此應(yīng)用程序,您的最終用戶只需要在他們的機(jī)器上安裝一個(gè)合適的 Python 3 解釋器。與常規(guī) Zip 應(yīng)用程序相比,此類應(yīng)用程序的優(yōu)勢(shì)在于您的最終用戶無(wú)需安裝任何依賴項(xiàng)即可運(yùn)行該應(yīng)用程序。來(lái)試試看吧!
在上面的示例中,您使用 的-c選項(xiàng)zipapp來(lái)壓縮realpython_sa/.?對(duì)于具有許多依賴項(xiàng)且占用大量磁盤(pán)空間的應(yīng)用程序,此選項(xiàng)非常方便。
手動(dòng)創(chuàng)建 Python Zip 應(yīng)用程序
正如您已經(jīng)了解到的那樣,zipapp自 Python 3.5 以來(lái),標(biāo)準(zhǔn)庫(kù)中已經(jīng)提供了。如果您使用的 Python 版本低于該版本,那么您仍然可以手動(dòng)構(gòu)建 Python Zip 應(yīng)用程序,而無(wú)需zipapp.
在以下兩節(jié)中,您將學(xué)習(xí)如何使用zipfilePython 標(biāo)準(zhǔn)庫(kù)創(chuàng)建 Zip 應(yīng)用程序。您還將學(xué)習(xí)如何使用一些命令行工具來(lái)完成相同的任務(wù)。
使用 Python 的?zipfile
您已經(jīng)擁有realpython/包含reader應(yīng)用程序源文件的目錄。從該目錄手動(dòng)構(gòu)建 Python Zip 應(yīng)用程序的下一步是將其存檔到 ZIP 文件中。為此,您可以使用zipfile.?該模塊提供了方便的工具來(lái)創(chuàng)建、讀取、寫(xiě)入、附加和列出 ZIP 文件的內(nèi)容。
下面的代碼顯示了如何reader使用zipfile.ZipFile和其他一些工具創(chuàng)建Zip 應(yīng)用程序。例如,代碼依賴pathlib并stat讀取源目錄的內(nèi)容并為結(jié)果文件設(shè)置執(zhí)行權(quán)限:
# build_app.py import pathlib import stat import zipfile app_source = pathlib.Path("realpython/") app_filename = pathlib.Path("realpython.pyz") with open(app_filename, "wb") as app_file: # 1. Prepend a shebang line shebang_line = b"#!/usr/bin/env python3\n" app_file.write(shebang_line) # 2. Zip the app's source with zipfile.ZipFile(app_file, "w") as zip_app: for file in app_source.rglob("*"): member_file = file.relative_to(app_source) zip_app.write(file, member_file) # 3. Make the app executable (POSIX systems only) current_mode = app_filename.stat().st_mode exec_mode = stat.S_IEXEC app_filename.chmod(current_mode | exec_mode)
此代碼運(yùn)行三個(gè)必需的步驟,最終得到一個(gè)成熟的 Python Zip 應(yīng)用程序。第一步向應(yīng)用程序的文件中添加一個(gè)shebang 行。它open()在with語(yǔ)句中使用創(chuàng)建文件對(duì)象 (?app_file) 來(lái)處理應(yīng)用程序。然后它調(diào)用.write()在app_file.
注意:如果你在 Windows 上,你應(yīng)該用UTF-8編碼 shebang 行。如果您使用的是POSIX系統(tǒng),例如 Linux 和 macOS,您應(yīng)該使用sys.getfilesystemencoding()返回的任何文件系統(tǒng)編碼對(duì)其進(jìn)行編碼。
第二步使用ZipFile嵌套with語(yǔ)句壓縮應(yīng)用程序的源目錄內(nèi)容。該for循環(huán)遍歷文件中realpython/使用pathlib.Path.rglob()并將它們寫(xiě)入zip_app。請(qǐng)注意,.rglob()通過(guò)目標(biāo)文件夾遞歸搜索文件和目錄app_source。
member_file最終 ZIP 存檔中每個(gè)文件的文件名realpython/.?這就是您pathlib.Path.relative_to()在上面的示例中使用的原因。
最后,第三步使用pathlib.Path.chmod().?為此,您首先使用文件的當(dāng)前模式,pathlib.Path.stat()然后將此模式與按位OR 運(yùn)算符 (?)結(jié)合stat.S_IEXEC使用。請(qǐng)注意,此步驟僅對(duì) POSIX 系統(tǒng)有效。|
運(yùn)行這些步驟后,您的realpython.pyz應(yīng)用程序就可以運(yùn)行了。繼續(xù)并從命令行嘗試一下。
使用 Unix 命令行工具
如果您使用的是類 Unix 系統(tǒng),例如 Linux 和 macOS,那么您還可以使用命令行中的特定工具運(yùn)行上一節(jié)中的三個(gè)步驟。例如,您可以使用以下zip命令壓縮應(yīng)用程序源目錄的內(nèi)容:
$ cd realpython/ $ zip -r ../realpython.zip *
在本例中,您首先cd進(jìn)入realpython/目錄。然后使用帶有選項(xiàng)的命令將 的內(nèi)容壓縮realpython/到。此選項(xiàng)遞歸遍歷目標(biāo)目錄。realpython.zipzip-r
注意:另一種選擇是zipfile從命令行使用 Python?。
為此,請(qǐng)從realpython/目錄外部運(yùn)行以下命令:
$ python -m zipfile --create realpython.zip realpython/*
的--create命令行選項(xiàng)zipfile允許您從源目錄創(chuàng)建 ZIP 文件。*附加到realpython/目錄的星號(hào) (?)告訴將該目錄zipfile的內(nèi)容放在生成的 ZIP 文件的根目錄中。
下一步是在 ZIP 文件中添加一條 shebang 行realpython.zip,并將其另存為realpython.pyz.?為此,您可以在管道中使用echo和cat命令:
$ cd .. $ echo '#!/usr/bin/env python3' | cat - realpython.zip > realpython.pyz
該cd ..命令讓您退出realpython/.?的echo命令發(fā)送'#!/usr/bin/env python3'到標(biāo)準(zhǔn)輸出。管道符 (?|) 將標(biāo)準(zhǔn)輸出的內(nèi)容傳遞給cat命令。然后cat將標(biāo)準(zhǔn)輸出 (?-) 與 的內(nèi)容連接起來(lái)realpython.zip。最后,大于號(hào) (?>) 將cat輸出重定向到realpython.pyz文件。
最后,您可能希望使用以下chmod命令使應(yīng)用程序的文件可執(zhí)行:
$ chmod +x realpython.pyz
在這里,chmod將執(zhí)行權(quán)限 (?+x)添加到realpython.pyz.?現(xiàn)在您已準(zhǔn)備好再次運(yùn)行您的應(yīng)用程序,您可以像往常一樣從命令行執(zhí)行此操作。
使用第三方工具創(chuàng)建 Python 應(yīng)用程序
在 Python 生態(tài)系統(tǒng)中,您會(huì)發(fā)現(xiàn)一些與zipapp.?它們提供了更多功能,可以用于探索。在本節(jié)中,您將了解其中兩個(gè)第三方庫(kù):pex和shiv.
該pex項(xiàng)目提供了一個(gè)創(chuàng)建 PEX 文件的工具。PEX 代表Python 可執(zhí)行文件,是一種存儲(chǔ)獨(dú)立的可執(zhí)行 Python 虛擬環(huán)境的文件格式。該pex工具將這些環(huán)境打包成帶有 shebang 行和__main__.py模塊的ZIP 文件,允許您直接執(zhí)行生成的 PEX 文件。該pex工具是對(duì) PEP 441 中概述的想法的擴(kuò)展。
要使用 來(lái)創(chuàng)建可執(zhí)行應(yīng)用程序pex,您首先需要安裝它:
(venv) $ python -m pip install pex (venv) $ pex --help pex [-o OUTPUT.PEX] [options] [-- arg1 arg2 ...] pex builds a PEX (Python Executable) file based on the given specifications: sources, requirements, their dependencies and other options. Command-line options can be provided in one or more files by prefixing the filenames with an @ symbol. These files must contain one argument per line. ...
該pex工具提供了一組豐富的選項(xiàng),可讓您微調(diào) PEX 文件。以下命令顯示了如何為reader項(xiàng)目創(chuàng)建 PEX 文件:
(venv) $ pex realpython-reader -c realpython -o realpython.pex
此命令realpython.pex在您的當(dāng)前目錄中創(chuàng)建。這個(gè)文件是一個(gè) Python 可執(zhí)行文件,用于reader.?請(qǐng)注意,它pex處理PyPI的安裝reader及其所有依賴項(xiàng)。該reader項(xiàng)目在 PyPI 上可用,名稱為realpython-reader,這就是為什么您使用該名稱作為pex.
該-c選項(xiàng)允許您定義應(yīng)用程序?qū)⑹褂媚膫€(gè)控制臺(tái)腳本。在這種情況下,控制臺(tái)腳本realpython中定義setup.py的文件reader。該-o選項(xiàng)指定輸出文件。像往常一樣,您可以./realpython.pex從命令行執(zhí)行以運(yùn)行應(yīng)用程序。
由于內(nèi)容.pex文件被執(zhí)行之前解壓縮,PEX應(yīng)用程序解決的限制zipapp應(yīng)用程序,并允許您從執(zhí)行代碼.pyd,.so和.dll文件。
最后要注意的細(xì)節(jié)是pex在生成的 PEX 文件中創(chuàng)建和打包 Python 虛擬環(huán)境。這種行為使您的 Zip 應(yīng)用程序比使用zipapp.
您將在本節(jié)中學(xué)習(xí)的第二個(gè)工具是shiv.?它是在PEP 441描述構(gòu)建自成體系的Python郵編應(yīng)用程序的命令行實(shí)用程序的優(yōu)點(diǎn)shiv相比,zipapp是shiv會(huì)自動(dòng)包括所有在最后歸檔應(yīng)用程序的依賴關(guān)系,使他們?cè)赑ython的可用模塊搜索路徑。
要使用shiv,您需要從 PyPI 安裝它:
(venv) $ python -m pip install shiv (venv) $ shiv --help Usage: shiv [OPTIONS] [PIP_ARGS]... Shiv is a command line utility for building fully self-contained Python zipapps as outlined in PEP 441, but with all their dependencies included! ...
該--help選項(xiàng)顯示完整的使用消息,您可以查看該消息以快速了解shiv工作原理。
要使用 構(gòu)建 Python Zip 應(yīng)用程序shiv,您需要一個(gè)帶有setup.py或pyproject.toml文件的可安裝 Python 應(yīng)用程序。幸運(yùn)的是,reader來(lái)自 GitHub的原始項(xiàng)目滿足了這個(gè)要求。返回包含克隆reader/文件夾的目錄并運(yùn)行以下命令:
(venv) $ shiv -c realpython \ -o realpython.pyz reader/ \ -p "/usr/bin/env python3"
與該pex工具一樣,shiv可以-c選擇為應(yīng)用程序定義控制臺(tái)腳本。在-o和-p選項(xiàng)允許你提供一個(gè)輸出文件名和適當(dāng)?shù)腜ython解釋器,分別。
注意:上面的命令按預(yù)期工作。但是,shiv(0.5.2)的當(dāng)前版本會(huì)pip顯示關(guān)于它如何構(gòu)建包的棄用消息。由于直接shiv?接受pip參數(shù),您可以放置--use-feature=in-tree-build在命令的末尾,以便安全shiv使用pip。
不像zipapp,shiv使您可以使用.pyd,.so以及.dll文件在應(yīng)用程序的歸檔存儲(chǔ)。為此,shiv在存檔中包含一個(gè)特殊的引導(dǎo)功能。此函數(shù)將應(yīng)用程序的依賴項(xiàng)解壓到.shiv/您的主文件夾中的一個(gè)目錄中,并將它們添加到 Python 的sys.path.
此功能允許您創(chuàng)建獨(dú)立的應(yīng)用程序,其中包含部分用 C 和 C++ 編寫(xiě)的庫(kù)以提高速度和效率,例如NumPy。
結(jié)論
擁有一種快速有效的方式來(lái)分發(fā)您的 Python 可執(zhí)行應(yīng)用程序可以在滿足最終用戶的需求方面發(fā)揮重要作用。Python Zip 應(yīng)用程序?yàn)槟峁┝艘环N有效且易于訪問(wèn)的解決方案,用于捆綁和分發(fā)可立即運(yùn)行的應(yīng)用程序。您可以使用zipappPython 標(biāo)準(zhǔn)庫(kù)快速創(chuàng)建您自己的可執(zhí)行 Zip 應(yīng)用程序并將它們傳遞給您的最終用戶。
在本教程中,您學(xué)習(xí)了:
什么是Python的應(yīng)用郵編是
Zip 應(yīng)用程序如何在內(nèi)部工作
如何構(gòu)建您自己的 Python Zip 應(yīng)用程序?zipapp
什么是獨(dú)立的 Zip 應(yīng)用程序以及如何使用pip和創(chuàng)建它們zipapp
如何使用命令行工具手動(dòng)創(chuàng)建 Python Zip 應(yīng)用程序
有了這些知識(shí),您就可以快速創(chuàng)建 Python Zip 應(yīng)用程序,作為將 Python 程序和腳本分發(fā)給最終用戶的便捷方式。
Python Unix
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。