花下猫语: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
:提供了一个快速、可靠且易用的统一接口。
在 Astral,我们致力于为 Python 生态系统打造高性能的开发工具。我们最知名的产品是 Ruff,一个超高速的 Python 代码检查器 和 格式化工具。
在 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
sh
curl -LsSf https://astral.sh/uv/install.sh | sh
win
powershell
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
pip
sh
pip install uv
pipx
sh
pipx install uv
项目
uv 现在可以全面管理 Python 项目了。如果你用过 Poetry、PDM 或 Rye,那么 uv 的项目 API 对你来说一定不陌生。
项目 API 基于 Python 标准构建,使用 pyproject.toml
来定义项目元数据。
例如,你可以运行 uv init && uv add "fastapi>=0.112"
生成以下内容:
python
[project]
name = "hello-world"
version = "0.1.0"
readme = "README.md"
dependencies = ["fastapi>=0.112"]
从它开始,uv 将基于项目的依赖项创建一个锁文件。以下是一个示例片段:
toml
[[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
:
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
,但工作区共享一个锁文件,确保工作区使用一致的依赖集运行。
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
。
更多细节,请查阅工作区文档。
本文翻译并首发于 Python猫:(https://pythoncat.top/posts/2025-05-05-uv)
工具
uv 现在有两种新能力:
- 通过
uv tool install
在专用的隔离虚拟环境中安装命令行工具(如 Ruff) - 通过
uvx
直接运行一次性命令,无需预先安装
如果你使用过 pipx 或 npx,你会发现 uv 的工具 API 很熟悉。
比如,输入 uvx posting
就能直接运行 Darren Burns 开发的 posting
终端界面程序(TUI)。
使用 uvx
命令在终端中运行 posting 的示例。
工具 API 让你能集中管理系统上的 Python 工具。你可以:
- 用
uv tool list
查看所有已安装的工具及其可执行文件 - 用
uv tool upgrade --all
将所有工具升级到最新版本
uv 的工具 API 非常快,通过 uvx
执行命令几乎没有任何额外开销。
更多工具功能,请查阅工具文档。
Python 引导安装
uv 现在能够安装和管理 Python 本身,使其完全自引导:
shell
$ 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 所需的全部命令,没有任何隐藏步骤:
shell
$ 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:
python
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
自动将依赖声明嵌入到脚本中:
python
$ 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 生态的包管理挑战,欢迎联系我们。让我们携手共创更好的工具。