摘要:在本教程中,您探索了如何建立新的 Python Poetry 項目以及如何将 Poetry 添加到現有項目中。
本文分享自華為雲社群《使用 Python Poetry 進行依賴管理》,作者: Yuchuan。
當您的 Python 項目依賴于外部包時,您需要確定使用每個包的正确版本。更新後,軟體包可能無法像更新前那樣工作。Python Poetry 之類的依賴項管理器可幫助您指定、安裝和解析項目中的外部包。通過這種方式,您可以確定始終在每台機器上使用正确的依賴版本。
使用Poetry将幫助您啟動新項目、維護現有項目并掌握依賴項管理。您将準備好使用pyproject.toml檔案,這将是在 Python 項目中定義建構需求的标準。
要完成本教程并充分利用它,您應該對虛拟環境、子產品和包以及pip.
雖然本教程側重于依賴項管理,但 Poetry 還可以幫助您建構和打包項目。如果您想分享您的工作,那麼您甚至可以将您的 Poetry 項目釋出到Python Packaging Index (PyPI)。
在深入研究 Python Poetry 的細節之前,您需要了解一些先決條件。首先,您将閱讀本教程中将遇到的術語的簡短概述。接下來,您将安裝 Poetry 本身。
如果您曾經import在 Python 腳本中使用過語句,那麼您就已經使用過modules。其中一些子產品可能是您自己編寫的 Python 檔案。其他可能是内置子產品,例如datetime。但是,有時 Python 提供的還不夠。那時您可能會轉向外部的打包子產品。當您的 Python 代碼依賴于外部子產品時,您可以說這些包是您項目的依賴項。
您可以在PyPI 中找到不屬于Python 标準庫的包。在了解其工作原理之前,您需要在系統上安裝 Poetry。
要在指令行中使用 Poetry,您應該在系統範圍内安裝它。如果您隻是想嘗試一下,那麼您可以使用pip. 但是您應該謹慎嘗試這種方法,因為 Poetry 将安裝自己的依賴項,這可能會與您在項目中使用的其他包沖突。
安裝 Poetry的推薦方法是使用官方install-poetry腳本。您可以手動下載下傳并運作此Python 檔案,也可以在下方選擇您的作業系統以使用相應的指令:
視窗
Linux + macOS
注意:有些使用者在 Windows 10 上使用 PowerShell 指令時會報告錯誤。
在輸出中,您應該看到安裝完成的消息。您可以poetry --version在終端中運作以檢視是否poetry有效。此指令将顯示您目前的 Poetry 版本。如果要更新 Poetry,則可以運作poetry self update.
安裝 Poetry 後,是時候看看 Poetry 是如何工作的了。在本節中,您将學習如何開始一個新的 Poetry 項目以及如何将 Poetry 添加到現有項目中。您還将看到項目結構并檢查pyproject.toml檔案。
您可以使用new指令和項目名稱作為參數來建立新的 Poetry 項目。在本教程中,該項目稱為rp-poetry. 建立項目,然後進入新建立的目錄:
通過運作poetry new rp-poetry,您可以建立一個名為 的新檔案夾rp-poetry/。當您檢視檔案夾内部時,您會看到一個結構:
Poetry 會自動為您規範化包名。它将-項目名稱中的破折号 ( ) 轉換_為檔案夾名稱中的下劃線 ( ) rp_poetry/。否則,Python 中将不允許使用該名稱,是以您無法将其作為子產品導入。為了更好地控制建立包名稱,您可以使用該--name選項以不同于項目檔案夾的方式命名:
如果您更喜歡将源代碼存儲在額外的src/父檔案夾中,那麼 Poetry 可以讓您使用以下--src标志來遵守該約定:
通過添加--src标志,您建立了一個名為 的檔案夾src/,其中包含您的rp_poetry/目錄:
建立新的 Poetry 項目時,您将立即收到一個基本的檔案夾結構。
該rp_poetry/子檔案夾本身是不是很壯觀呢。在這個目錄中,你會找到一個__init__.py包含你的包版本的檔案:
當您跳到tests/檔案夾并打開 時test_rp_poetry.py,您會注意到它rp_poetry已經是可導入的:
Poetry 還為該項目添加了第一個測試。該test_version()函數檢查 的__version__變量是否rp_poetry/__init__.py包含預期的版本。但是,該__init__.py檔案并不是您定義包版本的唯一位置。另一個位置是pyproject.toml檔案。
使用 Poetry 最重要的檔案之一是pyproject.toml檔案。這個檔案不是 Poetry 的發明。這是 PEP 518 中定義的配置檔案标準:
此 PEP 指定 Python 軟體包應如何指定它們具有的建構依賴項以執行其選擇的建構系統。作為本規範的一部分,為軟體包引入了一個新的配置檔案,用于指定它們的建構依賴項(期望相同的配置檔案将用于未來的配置細節)。(來源)
作者考慮了上面引用中提到的“新配置檔案”的幾種檔案格式。最後,他們決定采用TOML格式,即Tom's Obvious Minimal Language 的縮寫。在他們看來,TOML 足夠靈活,比其他選項(YAML、JSON、CFG 或 INI)具有更好的可讀性和更少的複雜性。要檢視 TOML 的外觀,請打開pyproject.toml檔案:
您可以在pyproject.toml檔案中看到四個部分。這些部分稱為表。它們包含諸如 Poetry 之類的工具識别和用于依賴項管理或建構例程的指令。
如果表名是特定于工具的,則必須以tool.為字首。通過使用這樣的子表,您可以為項目中的不同工具添加說明。在這種情況下,隻有tool.poetry. 但是,你可能會看到這樣的例子[tool.pytest.ini_options]為pytest在其他項目中。
在[tool.poetry]上面第 3 行的子表中,您可以存儲有關您的 Poetry 項目的一般資訊。您的可用鍵由 Poetry 定義。雖然有些鍵是可選的,但您必須指定四個鍵:
name: 你的包名
version: 包的版本,最好遵循語義版本控制
description:您的包裹的簡短描述
authors: 作者清單,格式 name <email>
第[tool.poetry.dependencies]9 行和[tool.poetry.dev-dependencies]第 12行的子表對于您的依賴項管理至關重要。在下一部分向 Poetry 項目添加依賴項時,您将了解有關這些子表的更多資訊。現在,重要的是要認識到的包相關性和發展依賴之間的差別。
該pyproject.toml檔案的最後一個表位于第[build-system]15 行。該表定義了 Poetry 和其他建構工具可以使用的資料,但由于它不是特定于工具的,是以它沒有字首。Poetry 建立了pyproject.toml具有兩個鍵的檔案:
requires:建構包所需的依賴項清單,使此鍵成為必需
build-backend:用于執行建構過程的 Python 對象
如果您想更多地了解pyproject.toml檔案的這一部分,那麼您可以通過閱讀PEP 517 中的源代碼樹來了解更多資訊。
當您使用 Poetry 開始一個新項目時,這就是pyproject.toml您開始的檔案。随着時間的推移,您将添加有關您的包和您正在使用的工具的配置詳細資訊。随着 Python 項目的增長,您的pyproject.toml檔案也會随之增長。對于子表[tool.poetry.dependencies]和[tool.poetry.dev-dependencies]. 在下一節中,您将了解如何擴充這些子表。
一旦你設定了一個 Poetry 項目,真正的工作就可以開始了。一旦 Poetry 到位,您就可以開始編碼。在此過程中,您将了解 Poetry 如何為您提供虛拟環境并處理您的依賴項。
當您開始一個新的 Python 項目時,建立一個虛拟環境是一種很好的做法。否則,您可能會混淆來自不同項目的不同依賴項。使用虛拟環境是 Poetry 的核心功能之一,它永遠不會幹擾您的全局 Python 安裝。
但是,Poetry 不會在您啟動項目時立即建立虛拟環境。您可以通過讓 Poetry 列出連接配接到目前項目的所有虛拟環境來确認 Poetry 尚未建立虛拟環境。如果你還沒有,cd進入rp-poetry/然後運作一個指令:
目前,不應該有任何輸出。
當您運作某些指令時,Poetry 會一路建立一個虛拟環境。如果您想更好地控制虛拟環境的建立,那麼您可能決定明确告訴 Poetry 您要為其使用哪個 Python 版本,然後從那裡開始:
使用此指令,您将使用與安裝 Poetry 相同的 Python 版本。使用python3的作品,當你在你的Python可執行程式PATH。
注意:或者,您可以将絕對路徑傳遞給 Python 可執行檔案。它應該與您可以在pyproject.toml檔案中找到的 Python 版本限制相比對。如果沒有,那麼您可能會遇到麻煩,因為您使用的 Python 版本與項目所需的版本不同。在您的環境中運作的代碼在另一台機器上可能有問題。
更糟糕的是,外部包通常依賴于特定的 Python 版本。是以,安裝包的使用者可能會收到錯誤消息,因為您的依賴項版本與其 Python 版本不相容。
當你運作時env use,你會看到一條消息:
如您所見,Poetry 為您的項目環境建構了一個唯一名稱。該名稱包含項目名稱和 Python 版本。中間看似随機的字元串是您的父目錄的哈希值。通過中間的這個唯一字元串,Poetry 可以處理系統上具有相同名稱和相同 Python 版本的多個項目。這很重要,因為預設情況下,Poetry 在同一個檔案夾中建立所有虛拟環境。
Poetry 無需任何其他配置,在virtualenvs/Poetry緩存目錄的檔案夾中建立虛拟環境:

如果要更改預設緩存目錄,則可以編輯Poetry 的配置。當您已經在使用virtualenvwrapper或其他第三方工具來管理您的虛拟環境時,這會很有用。要檢視目前配置,包括已配置的cache-dir,您可以運作以下指令:
通常,您不必更改此路徑。如果您想了解有關與 Poetry 的虛拟環境互動的更多資訊,那麼 Poetry 文檔包含有關管理環境的一章。
隻要您在項目檔案夾中,Poetry 就會使用與之關聯的虛拟環境。如果您有疑問,可以env list再次運作以下指令檢查虛拟環境是否已激活:
這将顯示類似rp-poetry-AWdWY-py3.9 (Activated). 有了激活的虛拟環境,您就可以開始管理一些依賴項并看到 Poetry 的魅力了。
Poetry 的一個關鍵元素是它對依賴項的處理。在開始之前,先看一下檔案中的兩個依賴表pyproject.toml:
目前為您的項目聲明了兩個依賴項。一個是 Python 本身。另一個是pytest,一個廣泛使用的測試架構。正如您之前看到的,您的項目包含一個tests/檔案夾和一個test_rp_poetry.py檔案。使用pytest作為依賴項,Poetry 可以在安裝後立即運作您的測試。
注意:在編寫本教程時,pytest使用Python 3.10運作Poetry不起作用。Poetry 安裝了一個與 Python 3.10 不相容的 pytest 版本。
Poetry 開發人員已經意識到這個問題,它将随着 Poetry 1.2 的釋出而得到修複。
確定您在rp-poetry/項目檔案夾中并運作指令:
使用該install指令,Poetry 檢查您的pyproject.toml檔案中的依賴項,然後解析并安裝它們。當您有許多依賴項需要使用不同版本的不同第三方包時,解析部分尤其重要。在安裝任何包之前,Poetry 會确定哪個版本的包滿足其他包設定為其要求的版本限制。
除了pytest它的要求之外,Poetry 還安裝了項目本身。這樣,您可以立即導入rp_poetry到您的測試中:
安裝項目包後,您可以導入rp_poetry測試并檢查__version__字元串。随着pytest安裝,您可以使用poetry run指令來執行測試:
您目前的測試已成功運作,是以您可以放心地繼續編碼。但是,如果您仔細觀察第 3 行,就會發現有些奇怪。它說pytest-5.4.3,5.2不像pyproject.toml檔案中所說的那樣。接得好!
回顧一下,檔案中的pytest依賴項pyproject.toml如下所示:
^前面的插入符号 ( )5.2具有特定的含義,它是 Poetry 提供的版本限制之一。這意味着 Poetry 可以安裝與版本字元串最左邊的非零數字比對的任何版本。這意味着5.4.3允許使用。版本6.0将不被允許。
當 Poetry 嘗試解析依賴版本時,像插入符号這樣的符号将變得很重要。如果隻有兩個要求,這并不太難。你聲明的依賴越多,它就越複雜。讓我們看看 Poetry 如何通過将新包安裝到您的項目中來處理這個問題。
您pip之前可能使用過安裝不屬于 Python 标準庫的包。如果您pip install使用包名作為參數運作,則pip在Python Package Index上查找包。您可以以同樣的方式使用 Poetry。
如果你想在requests你的項目中添加一個外部包,那麼你可以運作一個指令:
通過運作poetry add requests,您正在将最新版本的requests庫添加到您的項目中。您可以使用版本限制,requests<=2.1或者requests==2.24如果您想更具體。當您不添加任何限制時,Poetry 将始終嘗試安裝最新版本的軟體包。
有時,您隻想在開發環境中使用某些包。使用pytest,您已經發現其中之一。另一種常見的庫包括一個代碼格式化像黑色,一個文檔生成等斯芬克斯,和類似的一個靜态分析工具pylint的,Flake8,mypy,或coverage.py。
要明确告訴 Poetry 一個包是一個開發依賴項,您可以poetry add使用該--dev選項運作。您還可以使用速記-D選項,它與以下内容相同--dev:
您添加requests為項目依賴項和black開發依賴項。Poetry 在背景為您做了一些事情。一方面,它将您聲明的依賴項添加到pyproject.toml檔案中:
Poetry 将該requests包作為項目依賴項添加到tool.poetry.dependencies表中,同時将其black作為開發依賴項添加到tool.poetry.dev-dependencies.
區分項目依賴項和開發依賴項可以防止安裝使用者不需要運作程式的需求。開發依賴項僅與您的包的其他開發人員相關,他們希望pytest使用black. 當使用者安裝您的軟體包時,他們隻會安裝requests它。
注意: 您可以更進一步并聲明可選的依賴項。當您想讓使用者選擇安裝一個不需要但增強您的包的特定資料庫擴充卡時,這會很友善。您可以在Poetry 文檔 中了解有關可選依賴項的更多資訊。
除了對pyproject.toml檔案的更改之外,Poetry 還建立了一個名為poetry.lock. 在此檔案中,Poetry 會跟蹤您在項目中使用的所有包和确切版本。
當您運作該poetry add指令時,Poetry 會自動更新pyproject.toml并固定poetry.lock檔案中的已解析版本。但是,您不必讓 Poetry 完成所有工作。您可以手動向pyproject.toml檔案添加依賴項并在之後鎖定它們。
如果您想使用 Python 建構網絡爬蟲,那麼您可能需要使用Beautiful Soup來解析您的資料。将其添加到檔案中的tool.poetry.dependencies表中pyproject.toml:
通過添加beautifulsoup4 = "4.10.0",您告訴 Poetry 它應該完全安裝這個版本。當您向pyproject.toml檔案添加需求時,它尚未安裝。隻要poetry.lock你的項目中沒有檔案存在,你就可以poetry install在手動添加依賴後運作,因為 Poetry 會先查找poetry.lock檔案。如果沒有找到,Poetry 将解析pyproject.toml檔案中列出的依賴項。
一旦poetry.lock檔案存在,Poetry 将依賴該檔案來安裝依賴項。僅運作poetry install會觸發警告,提示兩個檔案不同步并會産生錯誤,因為 Poetry 尚不知道beautifulsoup4項目中的任何版本。
要将pyproject.toml檔案中手動添加的依賴項固定到poetry.lock,您必須首先運作以下poetry lock指令:
通過運作poetry lock,Poetry 處理pyproject.toml檔案中的所有依賴項并将它們鎖定到poetry.lock檔案中。詩歌并不止于此。運作時poetry lock,Poetry 還會遞歸周遊并鎖定您的直接依賴項的所有依賴項。
注意:poetry lock如果有适合您的版本限制的新版本可用,該指令還會更新您現有的依賴項。如果您不想更新poetry.lock檔案中已有的任何依賴項,則必須将--no-update選項添加到poetry lock指令中:
在這種情況下,Poetry 僅解析新的依賴項,但poetry.lock不會更改檔案中的任何現有依賴項版本。
現在您已經固定了所有依賴項,是時候安裝它們以便您可以在您的項目中使用它們。
如果您按照上一節中的步驟操作,那麼您已經安裝pytest并black使用了該poetry add指令。您還鎖定了beautifulsoup4,但您還沒有安裝 Beautiful Soup。要驗證beautifulsoup4尚未安裝,請使用以下指令打開Python 解釋器poetry run:
執行poetry run python3将在 Poetry 的環境中打開一個互動式REPL會話。首先,嘗試導入requests. 這應該完美無缺。然後嘗試 importing bs4,這是 Beautiful Soup 的子產品名稱。這應該會引發錯誤,因為尚未安裝 Beautiful Soup:
正如預期的那樣,您可以requests毫無困難地導入,并且bs4找不到子產品。通過鍵入exit()并點選退出互動式 Python 解釋器Enter。
使用poetry lock指令鎖定依賴項後,您必須運作該poetry install指令,以便您可以在項目中實際使用它們:
通過運作poetry install,Poetry 讀取poetry.lock檔案并安裝其中聲明的所有依賴項。現在,bs4已準備好在您的項目中使用。要對此進行測試,請輸入poetry run python3并導入bs4Python 解釋器:
完美的!這次沒有錯誤,并且您擁有您聲明的确切版本。這意味着 Beautiful Soup 已正确固定在您的poetry.lock檔案中,已安裝在您的項目中,并且可以使用了。要列出項目中的可用包并檢查它們的詳細資訊,您可以使用該show指令。當您使用--help标志運作它時,您将看到如何使用它:
要檢查包,您可以使用show包名稱作為參數,也可以使用--tree選項将所有依賴項以樹的形式列出。這将幫助您檢視項目的嵌套需求。
為了更新您的依賴項,Poetry 根據兩種情況提供了不同的選項:
更新版本限制内的依賴項。
更新版本限制之外的依賴項。
您可以在pyproject.toml檔案中找到版本限制。當新版本的依賴項仍然滿足您的版本限制時,您可以使用以下update指令:
該update指令将在版本限制内更新所有包及其依賴項。之後,Poetry 将更新您的poetry.lock檔案。
如果你想更新一個或多個特定的包,那麼你可以将它們作為參數列出:
使用此指令,Poetry 将搜尋滿足檔案中列出的版本限制的新版本requests和新版本。然後它将解析您項目的所有依賴項并将版本固定到您的檔案中。您的檔案将保持不變,因為列出的限制仍然有效。beautifulsoup4pyproject.tomlpoetry.lockpyproject.toml
如果要使用比pyproject.toml檔案中定義的版本更高的版本來更新依賴項,則需要pyproject.toml事先調整檔案。另一種選擇是add使用版本限制或latest标簽運作指令:
當您運作add帶有latest标記的指令時,它會查找包的最新版本并更新您的pyproject.toml檔案。包含latest标簽或版本限制對于使用該add指令至關重要。如果沒有它,您會收到一條消息,表明該包已存在于您的項目中。另外,不要忘記--dev為開發依賴項添加标志。否則,您會将包添加到正常依賴項中。
添加新版本後,您必須運作install您在上一節中學到的指令。隻有這樣,您的更新才會被鎖定到poetry.lock檔案中。
如果您不确定更新會為您的依賴項引入哪些基于版本的更改,您可以使用該--dry-run标志。此标志适用于指令update和add指令。它在您的終端中顯示操作而不執行任何操作。這樣,您可以安全地發現版本更改并決定哪種更新方案最适合您。
雖然pyproject.toml檔案中的版本要求可能很寬松,但 Poetry 會鎖定您在poetry.lock檔案中實際使用的版本。這就是為什麼在使用Git 時應該送出此檔案的原因。通過poetry.lock在Git 存儲庫中提供檔案,您可以確定所有開發人員都将使用所需軟體包的相同版本。當您遇到包含poetry.lock檔案的存儲庫時,最好使用 Poetry。
使用poetry.lock,您可以確定您使用的版本與其他開發人員使用的版本完全相同。如果其他開發人員不使用 Poetry,您可以将其添加到未使用 Poetry 設定的現有項目中。
很有可能,您的項目不是從poetry new指令開始的。或者,您可能繼承了一個不是用 Poetry 建立的項目,但現在您想使用 Poetry 進行依賴管理。在這些類型的情況下,您可以将 Poetry 添加到現有的 Python 項目中。
如果您的項目隻包含一些 Python 檔案,那麼您仍然可以添加 Poetry 作為未來建構的基礎。在這個例子中,隻有一個檔案,hello.py:
這個腳本唯一能做的就是輸出字元串"Hello World!"。但也許這隻是一個宏偉項目的開始,是以您決定将 Poetry 添加到您的項目中。poetry new您将使用以下poetry init指令,而不是使用之前的指令:
該poetry init指令将啟動互動式會話以建立pyproject.toml檔案。 Poetry 為您提供了大多數需要設定的配置的建議,您可以按下Enter以使用它們。當您不聲明任何依賴項時,pyproject.tomlPoetry 建立的檔案如下所示:
内容看起來與您在前幾節中經曆的示例相似。
現在您可以使用 Poetry 項目提供的所有指令。有了pyproject.toml檔案,您現在可以運作腳本:
因為 Poetry 沒有找到任何可以使用的虛拟環境,是以它在執行您的腳本之前建立了一個新環境。執行此操作後,它會顯示您的Hello World!消息而沒有任何錯誤。這意味着您現在有一個正在運作的 Poetry 項目。
有時您的項目已經有一個requirements.txt檔案。看看requirements.txt這個Python 網絡爬蟲的檔案:
使用該cat實用程式,您可以讀取檔案并将内容寫入标準輸出。在本例中,它顯示了網絡爬蟲項目的依賴項。使用 建立 Poetry 項目後poetry init,您可以将該cat實用程式與以下poetry add指令結合使用:
當需求檔案像這樣簡單時,使用poetry add和cat可以為您節省一些手動工作。
requirements.txt然而,有時檔案會更複雜一些。在這些情況下,您可以執行測試運作并檢視結果,或者手動将需求添加到檔案中的[tool.poetry.dependencies]表中pyproject.toml。要檢視您的結構pyproject.toml是否有效,您可以在poetry check之後運作。
在某些情況下,您必須有一個requirements.txt檔案。例如,也許您想在 Heroku 上托管您的 Django 項目。對于這種情況,Poetry 提供了export指令。如果你有一個 Poetry 項目,你可以requirements.txt從你的poetry.lock檔案中建立一個檔案:
poetry export以這種方式使用該指令會建立一個requirements.txt包含散列和環境标記的檔案。這意味着您可以確定處理與poetry.lock檔案内容類似的非常嚴格的要求。如果您還想包含您的開發依賴項,您可以添加--dev到指令中。要檢視所有可用選項,您可以選中poetry export --help。
本教程向您介紹了 Poetry 的依賴管理。在此過程中,您使用了一些 Poetry 的指令行界面 (CLI) 指令:
您可以檢視Poetry CLI 文檔以了解有關上述指令和 Poetry 提供的其他指令的更多資訊。您還可以poetry --help直接在終端中運作以檢視資訊!
在本教程中,您探索了如何建立新的 Python Poetry 項目以及如何将 Poetry 添加到現有項目中。Poetry 的一個關鍵部分是pyproject.toml檔案。與 結合使用poetry.lock,您可以確定安裝項目所需的每個包的确切版本。當您跟蹤poetry.lockGit 存儲庫中的檔案時,您還要確定項目中的所有其他開發人員在他們的機器上安裝相同的依賴項版本。
點選關注,第一時間了解華為雲新鮮技術~