uv:统一的 Python 包管理
花下猫语:uv 项目自发布起就大受欢迎,目前 Github star 52.6 K,远超过它的同类竞品们。前不久,它的创始人在 X 上披露了一组惊人的数据:uv 曾占据了 PyPI 超过 20% 的流量,用户每天通过它发起约 4-5 亿次下载请求!

我在去年翻译过 uv 首发时的新闻文章,根据博客后台不完整的统计,从 Google 搜索进入的访问量已经超过 3000,妥妥成为了我博客的搜索访问 TOP 1!这侧面也反映出 uv 的火爆程度!
uv 刚过一周岁不久,如此年轻,成绩斐然啊。趁着这波热点(实际是假期有时间),我抽空把 uv 重要版本更新的文章也翻译出来了,enjoy reading~
译者:豌豆花下猫@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
:提供了一个快速、可靠且易用的统一接口。在 2 月份,我们发布了 uv,这是一个极快的 Python 包安装器和依赖解析器,最初设计为常见
pip
工作流的即插即用替代方案。今天,我们宣布 uv 自首次发布以来最大规模的功能扩展:
- 端到端项目管理:
uv run
、uv lock
和uv sync
。uv 现在能基于标准元数据创建跨平台的锁文件,并利用该文件来安装依赖。它是 Poetry、PDM 和 Rye 等工具的高性能替代品。 - 工具管理:
uv tool install
和uv tool run
(别名为uvx
)。uv 能在隔离的虚拟环境中安装命令行工具,还能无需先安装就直接执行命令(如uvx ruff check
)。它是pipx
等工具的高性能替代品。 - Python 安装:
uv python install
。uv 现在可以直接帮你安装 Python,替代pyenv
等工具。 - 脚本执行:uv 现在可以管理基于 PEP 723 标准的单文件 Python 脚本,这些脚本内部包含依赖元数据。只需要一个简单的
uv run
命令就能执行这些独立的 Python 脚本。
…所有功能背后都是一个跨平台的超高速依赖解析器在支撑。

上图展示了启用所有可选依赖项时解析 Transformers 项目的速度对比:上方无缓存状态,下方启用了缓存。
并且所有功能都包含在新的、全面的文档中。
这些新功能每一项都大大扩展了 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
[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
,你再也不需要操心虚拟环境的激活、依赖包的管理或者项目的维护更新。一切都变得无比简单。想了解更多详情,请查阅项目文档。
本文翻译并首发于 Python猫:uv:统一的 Python 包管理
依赖源:可编辑依赖、相对路径等
uv 基于 Python 标准构建,如 PEP 621。同时,它还添加了一些在标准中没有的功能,这些功能对本地开发至关重要,如相对路径和可编辑依赖。
在标准的
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
路径下的可编辑的包加到开发环境中。这样,项目的依赖定义保持不变,只是依赖的来源发生了变化。详细内容请查阅依赖源文档。
工作区
受 Cargo 相同概念的启发,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
。更多细节,请查阅工作区文档。
工具
uv 现在有两种新能力:
- 通过
uv tool install
在专用的隔离虚拟环境中安装命令行工具(如 Ruff) - 通过
uvx
直接运行一次性命令,无需预先安装
比如,输入
uvx posting
就能直接运行 Darren Burns 开发的 posting
终端界面程序(TUI)。使用
uvx
命令在终端中运行 posting 的示例。工具 API 让你能集中管理系统上的 Python 工具。你可以:
- 用
uv tool list
查看所有已安装的工具及其可执行文件 - 用
uv tool upgrade --all
将所有工具升级到最新版本
uv 的工具 API 非常快,通过
uvx
执行命令几乎没有任何额外开销。更多工具功能,请查阅工具文档。
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 版本的问题。
更多细节,请查阅脚本文档。
为规模化而构建
在 Astral,我们的指导原则之一是:“为所有人设计,为规模化构建(Design for everyone, build for scale)。”
我们希望打造的工具对初学者友好,但同时又能满足最大型 Python 项目的需求。
我们相信 uv 已经很好地实现了这两个目标。
如果你在组织里使用 uv,并想一起解决 Python 生态的包管理挑战,欢迎联系我们。让我们携手共创更好的工具。
附录
