uv :新一代的 Python 包管理工具

发布: 2025-08-03   上次更新: 2025-11-02   分类: 效率工具   标签: uv python

文章目录

今天我想介绍一个新的 Python 包管理工具:uv。它是一个采用 Rust 写的包管理器,旨在提供更快、更可靠的包管理体验:

说实话,作为一个不是靠 Python 吃饭的程序员,每次写 Python 我的心情都挺复杂的,一方面是因为 Python 的语法和生态都很棒,我能够很快写出满足需求的脚本;另一方面是因为 Python 的包管理工具实在太糟糕了,每次稍微大型的 Python 项目,我都要去搜索一下最佳实践是什么,该用哪个 lsp、formatter,以及怎么管理虚拟环境难等一堆问题。

uv 的出现让我看到了希望,它的设计理念是简化 Python 的包管理流程,提供一个统一的工具来处理所有的包管理任务。

安装 uv

uv 的安装非常简单,只需要运行下面的命令:

1curl -LsSf https://install.astral.sh | sh

安装完成后,我们需要将 ~/.local/bin 目录添加到 PATH 中:

1export PATH="$HOME/.local/bin:$PATH"

然后我们可以通过下面的命令来验证 uv 是否安装成功:

1uv --version

管理多个 Python 版本

Python 的演进很奇怪,每个版本之间的差异都很大,导致很多时候需要特定版本的 Python 才能运行某些包或项目。因此多版本管理是个刚需,通过 uv,我们可以通过简单的命令来安装和切换不同的 Python 版本。

1# 默认安装在 ~/.local/share/uv/python/ 目录下
2uv python install 3.12.4
3# pin 命令会在当前目录内创建 .python-version 文件,记录当前使用的 Python 版本
4uv python pin 3.12.4
5
6uv python list
7uv python uninstall 3.12.4

管理虚拟环境

为了保证项目的依赖隔离,Python 社区推荐使用虚拟环境来管理项目的依赖。在 uv 之前,我们需要手动创建并激活,下面是一个典型的工作流:

1python -m venv venv
2source venv/bin/activate
3pip install -r requirements.txt
4# 退出虚拟环境
5deactivate

uv 的理念与此不同,它默认就会为每个项目创建一个虚拟环境,并且在安装依赖时自动激活这个虚拟环境。这样我们就不需要手动管理虚拟环境了。

项目结构

虚拟环境往往是和一个项目绑定的, uv init 就会创建一个如下目录结构的项目:

.
├──.gitignore
├──.python-version
├──README.md
├──main.py
├──pyproject.toml

在我们后续执行 uv add 命令安装依赖时,uv 会自动在当前目录下创建一个虚拟环境,并且后续所有 uv 的命令(比如 uv run uv sync )都会使用这个虚拟环境,这样我们就可以直接使用 uv 来管理项目的依赖,而不需要手动创建和激活虚拟环境。此时的目录结构是这样的:

.
├── .venv
│   ├── bin
│   ├── lib
│   └── pyvenv.cfg
├── .python-version
├── README.md
├── main.py
├── pyproject.toml
└── uv.lock

如果非 uv 用户,则也可以通过老的方式来使用这个项目

1source .venv/bin/activate
2python main.py
3# 等价于
4uv run main.py

pyproject.toml

pyproject.toml 是 Python 的标准配置文件,用于描述项目的元数据和依赖关系。uv 会自动生成这个文件,并且在我们添加依赖时会更新它:

1[project]
2name = "hello-world"
3version = "0.1.0"
4description = "Add your description here"
5readme = "README.md"
6dependencies = []

与 uv 相关的配置项会被放在 [tool.uv] 部分,一般情况下不需要配置。更多可参考:Configuration files | uv

uv.lock

uv.lock 是 uv 的锁文件,用于记录当前项目的依赖关系和版本信息。它类似于 npm 的 package-lock.json 或者 yarn.lock 文件。uv.lock 文件会在我们添加或更新依赖时自动生成和更新。

管理依赖

uv 提供了一个统一的命令来管理依赖,类似于 npm 的 install 命令。我们可以使用 uv add 命令来添加依赖,或者使用 uv remove 命令来删除依赖,uv 会自动更新 pyproject.toml 和 uv.lock 文件。

1uv add requests
2uv remove requests
3
4# Specify a version constraint
5uv add 'requests==2.31.0'
6
7# Add a git dependency
8uv add git+https://github.com/psf/requests

如果之前项目有 requirements.txt 文件,可以通过下面命令导入 pyproject.toml:

1uv add -r requirements.txt

如果手动修改了 pyproject.toml 文件,uv 会自动检测到变更并更新 uv.lock 文件。我们也可以使用 uv sync 命令来同步依赖,这会根据 pyproject.toml 文件安装或更新依赖。更多可以参考:Managing dependencies

运行项目

uv 提供了一个统一的命令来运行项目,类似于 npm 的 start 命令。我们可以使用 uv run 命令来运行项目,uv 会自动激活虚拟环境并执行指定的 Python 文件。

1uv add flask
2uv run -- flask run -p 3000

我们也可以使用 uv run 命令来运行任意的 Python 文件,比如:

1# main.py
2import flask
3
4print("hello world")
1uv run main.py

当然,我们也可以手动激活虚拟环境,然后运行 Python 文件,这和之前的方式是一样的:

1uv sync
2source .venv/bin/activate
3python main.py

执行脚本

PEP 723 中定义了内联脚本元信息(inline script metadata),我们可以直接通过在一个 Python 文件中添加特殊注释来定义脚本的元信息,比如:

 1# /// script
 2# dependencies = [
 3#   "httpx",
 4# ]
 5# ///
 6
 7import httpx
 8
 9resp = httpx.get("https://peps.python.org/api/peps.json")
10data = resp.json()
11print([(k, v["title"]) for k, v in data.items()][:10])

然后我们可以使用 uv run 命令来运行这个脚本,uv 会自动创建虚拟环境(默认在 ~/.cache/uv )、安装依赖并执行脚本。

我们可以通过如下命令来向一个脚本添加依赖:

1uv add --script example.py 'requests<3' 'rich'

最后,我们可以将这个脚本打包成一个可执行文件,方便分发和运行:

1#!/usr/bin/env -S uv run --script
2
3print("Hello, world!")

假设这个脚本名为: greet ,并且有执行权限,我们可以直接运行它:

1./greet
2# Hello, world!

更多用法,可以参考:https://docs.astral.sh/uv/guides/scripts/

tool

许多 Python 包提供了可以作为工具使用的应用程序。uv 具有专门的支持,便于调用和安装工具。比如:

1uv tool run ruff
2
3# uvx 就是 uv tool run 的别名
4uvx ruff

uv 在自动创建一个隔离的虚拟环境来运行工具,这样就可以避免工具之间的冲突。

如果一个工具经常使用,最好将其安装到持久环境中,并将其添加到 PATH 中( ~/.local/bin ),而不是反复调用 uvx。

我们可以使用 uv tool install 命令来安装工具,或者使用 uv tool uninstall 命令来删除工具。与 pip install 不同的是,安装工具并不会使其模块在当前环境中可用。例如,以下命令将失败:

1python -c "import ruff"

这种隔离对于减少工具、脚本和项目依赖关系之间的相互作用和冲突至关重要。

总结

毫无疑问,uv 是一个非常有前途的 Python 包管理工具,它的设计理念和功能都很符合现代开发的需求。它简化了 Python 的包管理流程,提供了一个统一的工具来处理所有的包管理任务。

再加上 Rust 的性能优势,uv 在速度和可靠性上都表现得非常出色。对于所有需要写 Python 的开发者来说,uv 是一个值得尝试的工具。

扩展阅读

评论

欢迎读者通过邮件与我交流,也可以在 MastodonTwitter 上关注我。