Python 有太多的包管理器

https://dublog.net/blog/so-many-python-package-managers/

Python 的包管理器太多

Python 是一個出色的編程語言。我用它來建立 web 應用程式、深度學習模型、遊戲和數值運算等。然而,Python 有一個方面多年來一直令人無法原諒地麻煩。這就是分散的 Python 封包和環境管理生態系統,這可以被這個 XKCD 漫畫所簡潔地代表。

在一個理智的世界裡,包管理應該像 Rust 的包管理器 Cargo-只需一個主配置檔 TOML 文件,您就可以列出您的依賴項和配置設置。TOML 文件放在一個封裝整個開發環境的文件夾中。為了額外的可重製性,每當您構建您的環境並解決所有包依賴關係時,一個*.lock 文件將記錄您所使用的所有封裝以及它們的版本和雜湊值。

目前,Python 的問題是沒有一個工具能很好地完成這一切,儘管有些接近。以下是我對十幾種 Python 封包管理/虛擬環境工具的概述:

啟蒙的 Python 封包管理

pip 和 venv

pip 是 Python 封包管理器的原始版本。在最近的版本 20.3,導入於 2020 年,pip 最終增加了回溯的依賴關係解決,這意味著如果檢測到不一致的狀態,它將返回並嘗試解決問題。不像這個列表中的許多其他工具,也不像 Rust 和 C#中的 Cargo 或 NuGet,pip 不與依賴關係一起管理環境。需要使用獨立工具,如 venv 或 virtualenv 來創建“虛擬環境”,這反過來完全與特定專案或專案目錄無關。

對於 pip 的一個關鍵過錯是刪除依賴時會發生的情況。刪除依賴並不會實際上刪除被原始依賴帶入的子依賴,因此容易產生許多可能的廢物。這實際上需要手動完成,或使用另一個工具如 pip-autoremove 刪除不再有用的子依賴。

要注意的一件事是 python 的 venv 工具實際上並不是為了創建不同版本的 Python 虛擬環境。為了實際執行這個任務,還有一個叫做 pyenv 的工具,它可以讓您在不同專案中自由切換系統 Python 的不同版本。我常常看到這個工具被濫用,使得忘記為不同的專案使用哪個版本的 Python 的風險加劇。

所以,pip 和 venv 組合可以讓您構建“虛擬環境”,而 pyenv 可以讓您切換 Python 版本。最自然的做法是有一個工具可以允許您在一個文件中指定 Python 版本和依賴項。pipenv 基本上完成了這個任務,並通過讓用戶在 Pipfile 中指定 Python 版本和依賴項以及在 Pipfile.lock 中鎖定依賴關係可選地與 pyenv 互通。

pipenv 的缺點是它的依賴關係解析不比底層使用的 pip 好。此外,2020 年,一個新的“Python Enhancement Proposal” PEP 621 被接受,定義了未來 Python 專案中的封包元數據應該如何統整,這使 Pipfile 和 Pipfile.lock 在長期來看不再那麼“慣用”…

統合 Python 配置:pyproject.toml 和 PEP-621

在 PEP-621 之前,一個給定 Python 專案中可能會存在許多配置文件:

requirements.txt: 專案的依賴關係,其可能包含或不包含包雜湊(出於安全原因),具體取決於如何設置。

setup.py 和 setup.cfg:一個腳本和一個配置文件,共同定義了依賴項和選項。

MANIFEST.in:告訴打包軟件(如 setuptools)要包含在封裝中的非代碼文件的類型。

tox.ini:由工具 tox 用於配置環境設置、依賴關係和測試命令(現在看到冗余了嗎?)

Pipfile 和 Pipfile.lock:供使用 pipenv 的人使用。

.pylintrc:用於設置像 black 和 isort 這樣的 linting 工具的配置。

environment.yml:專門供 conda 使用的用於定義依賴關係的配置文件,其中一些甚至不是 Python 封包。有趣的是,您可以分別指定 pip 依賴和 conda 依賴,即使 pip 封包在 conda 頻道上有對應的(可能更好的)版本也一樣!。

.condarc: Conda 的配置文件。

自然會存在所有這些工具和標準的大量冗余。實際上,實際上,根本沒有列舉給定封包的依賴項的標準方法,也沒有列舉如何設置 linting 工具和測試。

2020 年,PEP 621 被接受。這個提案實際上把所有東西都統合到一個 pyproject.toml 文件中,幾乎和 Rust 的 Cargo.toml 一樣,類似於 npm 使用的 package.json。當然,這導致了使用新標準的許多新的 Python 包管理器的散佈。進入 poetry、PDM、Flit 和 Hatch。

就目前而言,Poetry 是 Python 生態系統中目前最接近近似於使用像 Cargo 和 npm 這樣的工具的體驗的工具。不像 pip,這個算法是用 Rust 編寫的並且非常快!基準測試顯示,當涉及到依賴關係解析時,uv 至少比 poetry 快一個數量級。我完全期待 uv 在未來成熟和 API 穩定化時將超越 poetry。

希望有一天會有一個有課的解決方案,將 Python 封包管理帶到像 Javascript 和 Rust 開發生態系統中的簡單性和人體工學性。在此之前,我建議大多數應用于醍醐灌頂事實上,pip 解析緩慢,在有些複雜專案中,對於花費分鐘到數小時去尋找“失敗解析依賴項”而言,有些關鍵的異數。 如果是基本研究,則有些人認為拒絕解析依賴項就比等幾分鐘到幾小時更有意義。

via Hacker News

July 9, 2024 at 01:59AM

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *