uv:統一的 Python 包管理
花下貓語:uv 項目自發布起就大受歡迎,目前 Github star 52.6 K,遠超過它的同類競品們。前不久,它的創始人在 X 上披露了一組驚人的數據:uv 曾佔據了 PyPI 超過 20% 的流量,用戶每天通過它發起約 4-5 億次下載請求!
我在去年翻譯過 uv 首發時的新聞文章 [1],根據博客後臺不完整的統計,從 Google 搜索進入的訪問量已經超過 3000,妥妥成爲了我博客的搜索訪問 TOP 1!這側面也反映出 uv 的火爆程度!
uv 剛過一週歲不久,如此年輕,成績斐然啊。趁着這波熱點(實際是假期有時間),我抽空把 uv 重要版本更新的文章也翻譯出來了,enjoy reading~
作者:@charliermarsh[2]
譯者:豌豆花下貓 @Python 貓
英文:uv: Unified Python packaging (https://astral.sh/blog/uv-unified-python-packaging)
聲明:本翻譯是出於交流學習的目的,爲便於閱讀,部分內容略有改動。轉載請保留作者信息。
簡述:uv
是一個用 Rust 開發的超高性能 Python 包管理器。
我們最初在 2 月份發佈了 uv,作爲常見 pip
工作流的即插即用替代方案。(譯註:uv 在 2024.02 發佈,本文寫於 2024.08,翻譯於 2025.05)
今天,我們發佈一系列新功能,這些功能將 uv 從一個 pip
替代品擴展成爲一個端到端的解決方案,可用於管理 Python 項目、命令行工具、單文件腳本,甚至 Python 本身。
它就像是 Python 世界的Cargo
:提供了一個快速、可靠且易用的統一接口。
在 Astral,我們致力於爲 Python 生態系統打造高性能的開發工具。我們最知名的產品是 Ruff[3],一個超高速的 Python 代碼檢查器 [4] 和 格式化工具 [5]。
在 2 月份,我們發佈了 uv,這是一個極快的 Python 包安裝器和依賴解析器 [6],最初設計爲常見 pip
工作流的即插即用替代方案。【首發版本功能介紹】
今天,我們宣佈 uv 自首次發佈以來最大規模的功能擴展:
-
端到端項目管理 [7]:
uv run
、uv lock
和uv sync
。uv 現在能基於標準元數據創建跨平臺的鎖文件,並利用該文件來安裝依賴。它是 Poetry、PDM 和 Rye 等工具的高性能替代品。 -
工具管理 [8]:
uv tool install
和uv tool run
(別名爲uvx
)。uv 能在隔離的虛擬環境中安裝命令行工具,還能無需先安裝就直接執行命令(如uvx ruff check
)。它是pipx
等工具的高性能替代品。 -
Python 安裝 [9]:
uv python install
。uv 現在可以直接幫你安裝 Python,替代pyenv
等工具。 -
腳本執行 [10]:uv 現在可以管理基於 PEP 723[11] 標準的單文件 Python 腳本,這些腳本內部包含依賴元數據。只需要一個簡單的
uv run
命令就能執行這些獨立的 Python 腳本。
... 所有功能背後都是一個跨平臺的超高速依賴解析器在支撐。
上圖展示了啓用所有可選依賴項時解析 Transformers[12] 項目的速度對比:上方無緩存狀態,下方啓用了緩存。
並且所有功能都包含在新的、全面的文檔中。
這些新功能每一項都大大擴展了 uv 的能力範圍。但更獨特的是,它們組合起來形成了一個完整的工具鏈,大大簡化了 Python 開發過程。
結合 uv pip
(我們將它作爲一等功能,繼續維護並改進),uv 適用於任何 Python 工作流,從一次性腳本到大型的多包工作區開發。
你可以通過我們的獨立安裝程序或從 PyPI 安裝 uv:
curl
curl -LsSf https://astral.sh/uv/install.sh | sh
win
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
pip
pip install uv
pipx
pipx install uv
項目
uv 現在可以全面管理 Python 項目了。如果你用過 Poetry、PDM 或 Rye,那麼 uv 的項目 API 對你來說一定不陌生。
項目 API 基於 Python 標準構建,使用 pyproject.toml
來定義項目元數據。
例如,你可以運行 uv init && uv add "fastapi>=0.112"
生成以下內容:
[project]
name = "hello-world"
version = "0.1.0"
readme = "README.md"
dependencies = ["fastapi>=0.112"]
從它開始,uv 將基於項目的依賴項創建一個鎖文件。以下是一個示例片段:
[[package]]
name = "fastapi"
version = "0.112.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pydantic" },
{ name = "starlette" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2c/09/71a961740a1121d7cc90c99036cc3fbb507bf0c69860d08d4388f842196b/fastapi-0.112.1.tar.gz", hash = "sha256:b2537146f8c23389a7faa8b03d0bd38d4986e6983874557d95eed2acc46448ef", size = 291025 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/39/b0/0981f9eb5884245ed6678af234f2cbcd40f44570718caddc0360bdb4015d/fastapi-0.112.1-py3-none-any.whl", hash = "sha256:bcbd45817fc2a1cd5da09af66815b84ec0d3d634eb173d1ab468ae3103e183e4", size = 93163 },
]
[[package]]
name = "fastapi-cli"
version = "0.0.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typer" },
{ name = "uvicorn", extra = ["standard"] },
]
sdist = { url = "https://files.pythonhosted.org/packages/c5/f8/1ad5ce32d029aeb9117e9a5a9b3e314a8477525d60c12a9b7730a3c186ec/fastapi_cli-0.0.5.tar.gz", hash = "sha256:d30e1239c6f46fcb95e606f02cdda59a1e2fa778a54b64686b3ff27f6211ff9f", size = 15571 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/24/ea/4b5011012ac925fe2f83b19d0e09cee9d324141ec7bf5e78bb2817f96513/fastapi_cli-0.0.5-py3-none-any.whl", hash = "sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46", size = 9489 },
]
uv 的鎖文件就像項目依賴關係的完整快照,它能確保項目在不同機器上的運行環境保持一致。
這個鎖文件最大的優勢是_跨平臺_。不管你在哪個系統上生成鎖文件,它都能在其它平臺上正常工作。uv 爲每個平臺定義了一個獨特的解決方案,生成一個可讀且可審計的鎖文件,精確地定義了將安裝哪些軟件包。
例如:如果你在 macOS 上運行 uv lock
,uv 仍然會爲 Linux 和 Windows 生成解析方案,即使每個平臺上所需的依賴集稍有不同。
而且它做得非常快。在沒有任何緩存的情況下,uv 可以在大約半秒鐘內解析 Jupyter 項目的依賴項(在緩存預熱的情況下約爲 20 毫秒)。
解析 Jupyter 項目時無緩存(上)和有緩存(下)的對比。
項目 API 的核心是 uv run
命令,它能在項目專屬環境中運行命令,而且不需要手動激活虛擬環境。
uv run
非常快速。每次執行時,它都會自動重新鎖定和同步項目,確保你的環境始終是最新狀態。完全不需要手動干預。
換句話說,uv run
能確保你的命令每次都在一個一致的、受鎖文件管理的環境中運行。
使用 uv run
命令啓動 FastAPI 應用的示例。
有了 uv run
,你再也不需要操心虛擬環境的激活、依賴包的管理或者項目的維護更新。一切都變得無比簡單。
想了解更多詳情,請查閱項目文檔 [13]。
本文翻譯並首發於 Python 貓:https://pythoncat.top/posts/2025-05-05-uv
依賴源:可編輯依賴、相對路徑等
uv 基於 Python 標準構建,如 PEP 621[14]。同時,它還添加了一些在標準中沒有的功能,這些功能對本地開發至關重要,如相對路徑和可編輯依賴。
在標準的 project.dependencies
部分,你可以定義項目的依賴和可發佈的元數據。而在開發過程中,uv 還允許你通過 tool.uv.sources
爲這些依賴項指定替代來源。
例如,要使用本地的、可編輯版本的 anyio
,你可以運行 uv add --editable ../anyio
來生成以下 pyproject.toml
:
[project]
name = "hello-world"
version = "0.1.0"
readme = "README.md"
dependencies = ["anyio"]
[tool.uv.sources]
anyio = { path = "../anyio", editable = true }
當發佈到 PyPI 時,上述包會聲明對anyio
的依賴。但在本地開發時,使用 uv run
可以將 ../anyio
路徑下的可編輯的包加到開發環境中。這樣,項目的依賴定義保持不變,只是依賴的來源發生了變化。
詳細內容請查閱依賴源文檔 [15]。
工作區
受 Cargo 相同概念 [16] 的啓發,uv 支持工作區:一組管理在一起的包的集合。
想象這樣一個場景:在同一個 Git 倉庫中,有一個使用 FastAPI 構建的 Web 應用,還有多個作爲獨立 Python 包開發和維護的庫。
大多數大型 Python 項目最終都會用自己的方式來實現這個概念,它們通常藉助手寫腳本和自定義工具來管理各個包之間的關係。
uv 的工作區 API 爲大規模開發中的各種挑戰提供了一致、高效且具有創新性的解決方案。
在工作區中,每個包都有自己的 pyproject.toml
,但工作區共享一個鎖文件,確保工作區使用一致的依賴集運行。
[project]
name = "fastapi"
version = "0.1.0"
readme = "README.md"
dependencies = ["uvicorn"]
[tool.uv.sources]
uvicorn = { workspace = true }
[tool.uv.workspace]
members = ["libraries/*"]
在工作區的根目錄下,你可以運行命令來操作任何工作區包。例如,執行 uv run --package fastapi
或 uv run --package uvicorn
。
更多細節,請查閱工作區文檔 [17]。
工具
uv 現在有兩種新能力:
-
通過
uv tool install
在專用的隔離虛擬環境中安裝命令行工具(如 Ruff) -
通過
uvx
直接運行一次性命令,無需預先安裝
如果你使用過 pipx[18] 或 npx[19],你會發現 uv 的工具 API 很熟悉。
比如,輸入 uvx posting
就能直接運行 Darren Burns 開發的 posting
終端界面程序(TUI)。
使用 uvx
命令在終端中運行 posting 的示例。
工具 API 讓你能集中管理系統上的 Python 工具。你可以:
-
用
uv tool list
查看所有已安裝的工具及其可執行文件 -
用
uv tool upgrade --all
將所有工具升級到最新版本
uv 的工具 API 非常快,通過 uvx
執行命令幾乎沒有任何額外開銷。
更多工具功能,請查閱工具文檔 [20]。
Python 引導安裝
uv 現在能夠安裝和管理 Python 本身,使其完全自引導:
$ curl -LsSf https://astral.sh/uv/install.sh | sh
$ uv python install 3.12
如果你的機器上沒有安裝 Python,或者缺少特定的、所需的 Python 版本,除了顯式調用 uv python
外,uv 還可以根據需要,自動下載所需的 Python 版本(如 uv run
、uv venv
等命令)。
例如,以下是在新的 Ubuntu Docker 鏡像上運行 posting 所需的全部命令,沒有任何隱藏步驟:
$ apt-get update && apt-get install -y curl
$ curl -LsSf https://astral.sh/uv/install.sh | sh
$ source $HOME/.cargo/env
$ uvx posting
當你運行 uvx 命令時,uv 會一步到位地完成所有工作:
-
安裝 Python 3.12.4(文章寫作時的最新穩定版本)
-
創建虛擬環境
-
安裝必要的依賴包
-
啓動 posting 程序
整個過程無縫銜接,高效快捷。
單文件腳本
最後:uv 現在提供了對單文件 Python 腳本的一等支持,這些腳本可以內嵌依賴元數據,完全符合 PEP-723 標準。
例如,以下文件 main.py,它從 Python 增強提案索引中獲取前 10 個 PEP:
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
這個腳本依賴requests
和 rich
,但不包含任何顯式的依賴元數據。早些時候,你需要單獨管理這些依賴項,例如使用專門的 requirements.txt 文件。
現在,你可以使用 uv add
自動將依賴聲明嵌入到腳本中:
$ uv add --script main.py "requests<3" "rich"
$ cat main.py
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
有了它,uv run main.py
將在一個隔離的、臨時的虛擬環境中執行腳本,並安裝所有依賴項。
使用 uv run 執行帶有內嵌依賴項的單文件腳本的示例。
你也可以使用--with
標記在運行時指定依賴項,例如:uv run --with "requests<3" --with rich main.py
。
有了 uv 的 Python 引導安裝功能,你只需要 uv 就可以運行封閉式的、可重分發的單文件 Python 腳本,再也不用擔心虛擬環境、包管理或 Python 版本的問題。
更多細節,請查閱腳本文檔 [21]。
爲規模化而構建
在 Astral,我們的指導原則之一是:“爲所有人設計,爲規模化構建(Design for everyone, build for scale)。”
我們希望打造的工具對初學者友好,但同時又能滿足最大型 Python 項目的需求。
我們相信 uv 已經很好地實現了這兩個目標。
如果你在組織裏使用 uv,並想一起解決 Python 生態的包管理挑戰,歡迎聯繫我們。讓我們攜手共創更好的工具。
參考資料
[1]
新聞文章: https://pythoncat.top/posts/2024-03-05-uv
[2]
@charliermarsh: https://twitter.com/charliermarsh
[3]
Ruff: https://github.com/astral-sh/ruff
[4]
代碼檢查器: https://notes.crmarsh.com/python-tooling-could-be-much-much-faster
[5]
格式化工具: https://astral.sh/blog/the-ruff-formatter
[6]
Python 包安裝器和依賴解析器: https://pythoncat.top/posts/2024-03-05-uv
[7]
端到端項目管理: https://docs.astral.sh/uv/concepts/projects/
[8]
工具管理: https://docs.astral.sh/uv/concepts/tools/
[9]
Python 安裝: https://docs.astral.sh/uv/concepts/python-versions/
[10]
腳本執行: https://docs.astral.sh/uv/guides/scripts/
[11]
PEP 723: https://peps.python.org/pep-0723/
[12]
Transformers: https://github.com/huggingface/transformers
[13]
項目文檔: https://docs.astral.sh/uv/concepts/projects/
[14]
PEP 621: https://peps.python.org/pep-0621/
[15]
依賴源文檔: https://docs.astral.sh/uv/concepts/dependencies/#dependency-sources
[16]
Cargo 相同概念: https://doc.rust-lang.org/cargo/reference/workspaces.html
[17]
工作區文檔: https://docs.astral.sh/uv/concepts/workspaces/
[18]
pipx: https://github.com/pypa/pipx
[19]
npx: https://docs.npmjs.com/cli/v8/commands/npx
[20]
工具文檔: https://docs.astral.sh/uv/concepts/tools/
[21]
腳本文檔: https://docs.astral.sh/uv/guides/scripts/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/HGa1XCloVyM1Iu03No6fBQ