Python 包管理的新王 —— uv

Python 包管理的新王 —— uv

在之前的文章中我也多次提到 uv,但是我之前的认识太片面,现在回过头来看,有必要从头把 uv 的定位、安装方式、与 pip 的关系以及虚拟环境管理这些核心问题系统性地梳理一遍,帮助自己和读者建立一个清晰、准确的认知框架。普通开发者(尤其是 Windows 用户),推荐使用 standalone 方式安装 uv。uv 本身是为了管理 Python,而不是依赖 Python。


1. uv 是什么?为什么要关注安装方式?

uv 是由 Astral 团队用 Rust 编写的现代 Python 包与项目 管理器,旨在替代传统的 pip、venv、pip-tools 等工具链,提供更快、更一致的开发体验。

安装方式只决定 uv 自身如何存在和更新,不影响它管理项目依赖的能力。

在正式展开之前,有两个最核心的认知误区必须现纠正,否则后面的对比都是空中楼阁。

1. uv 的性能提升,到底提升在哪里?

很多人第一次听到 “uv 是 Rust 编写的 Python 包管理器” 时,会产生一个误解:

Rust 重写了 Python,所以 Python 程序运行更快了?

这个理解是不准确的,uv 提升的主要不是 Python 程序运行时性能(Runtime Performance),而是 Python 开发工具链性能(Tooling Performance)。简单来说:

阶段负责组件uv 是否提升
下载依赖包管理器✅ 大幅提升
解析依赖关系Resolver✅ 大幅提升
创建虚拟环境venv 管理✅ 提升
安装项目依赖Installer✅ 提升
Python 代码执行CPython❌ 基本不变
numpy/pandas 计算C/C++ 扩展❌ 基本不变

为什么 uv 能快? 不能简单理解成「因为 Rust 比 Python 快,所以 uv 比 pip 快」。Rust 本身只是基础。uv 的速度来自多方面的设计:高效的依赖解析器、并发网络请求、全局缓存、减少重复工作以及更高效的安装机制。Rust 让这些底层操作能够以较低开销运行,但真正带来整体体验提升的是「实现语言 + 算法 + 缓存 + 架构」的共同作用。

传统 Python 工作流:

1
2
3
4
5
6
pip
├── 查找包
├── 解析依赖
├── 下载文件
├── 安装包
└── 创建环境

uv 替代的是这一层:

1
2
3
4
5
6
uv (Rust)
├── 高效依赖解析
├── 并发下载
├── 全局缓存
├── 快速安装
└── 项目环境管理

其中,全局缓存和高效的安装机制,是 uv 能够大幅减少重复下载和重复安装开销的重要原因。

而不是:Python 代码 → CPython 解释器 → 程序运行,所以:

1
2
for i in range(100000000):
pass

这种代码不会因为使用 uv 安装依赖后,就变成 Rust 一样快。uv 的价值在于:让 Python 开发、部署、CI/CD 的过程更快,而不是让 Python 语言本身运行更快。

2. Rust 到底重写了什么?

另一个常见误解:uv 是不是把 numpy、requests、pandas 这些 Python 包全部用 Rust 重写了?

答案:不是。uv 重写的是 Python 生态中的「工具链」,例如以前 Python 项目通常需要:

1
2
3
4
5
pyenv        管理 Python 版本
venv 创建虚拟环境
pip 安装依赖
pip-tools 锁定版本
pipx 管理全局工具

而 uv 将这些功能整合到一个 Rust 实现的工具中:

1
2
3
4
5
6
7
8
uv
├── Python 版本管理
├── 虚拟环境管理
├── 依赖解析
├── 依赖安装
├── lock 文件管理
├── 项目运行
└── 全局工具隔离

但是安装完成之后:

1
2
3
4
5
6
7
8
uv
| 安装
↓
site-packages
├── requests
├── numpy
├── pandas
└── fastapi

这些包本身仍然是原来的 Python 包。运行程序时:

1
2
3
4
5
python app.py
↓
CPython
↓
requests / numpy / pandas

不会经过 uv。因此,更准确的理解是:uv 使用 Rust 重新实现并整合了 Python 生态中的依赖解析、安装、虚拟环境、Python 版本、项目管理等工具链能力,而不是用 Rust 重写整个 Python 生态。 这也是为什么把 uv 类比成其他语言里「管依赖」的工具:

1
2
3
C++ 里的 Conan / vcpkg
Rust 里的 Cargo
JavaScript 里的 npm / pnpm

它管理代码依赖,但不是这些依赖本身。


2. 两种安装方式的本质差异

功能对比 —— 完全一致,无论哪种安装方式,uv init / add / remove / sync / run / lock / build / publish / python install / venv / tool install 等功能完全相同——两种方式最终执行的是 同一套 Rust 编写的 uv 核心。

1. standalone 安装(官方推荐)

Windows:

1
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

安装后在 C:\Users\你的用户名\.local\bin 生成三个独立可执行文件:

文件用途
uv.exe主程序,项目与包管理入口
uvw.exe文件监听与自动重跑(uv w)
uvx.exe工具运行器(uv tool run),类似 pipx

这些都是完整的独立程序,像 git.exe、node.exe 一样,完全不依赖 Python。

2. pip 安装

1
pip install uv

实质是把 uv 当作 Python 包安装:Scripts/uv.exe 只是一个薄启动器,uv 会作为 Python 包安装到当前 Python 环境,因此它的生命周期依赖这个 Python 环境。Python 卸载 → uv 消失。

3. Linux / macOS 同样推荐 standalone

Linux 上同样推荐使用 standalone 方式安装 uv,不要通过 pip install uv 安装。因为 uv 本身就是用于管理 Python 环境的工具,让 uv 独立于 Python 存在,可以避免与系统 Python、多版本 Python 以及项目环境产生依赖耦合。官方推荐使用安装脚本:

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

安装后,uv 会作为独立二进制程序存在(通常位于 ~/.local/bin/uv),不依赖系统 Python。之后可以直接使用 uv python install 管理 Python 版本,使用 uv venv 创建虚拟环境,使用 uv add、uv sync 管理项目依赖。

无论 Windows、Linux 还是 macOS,核心原则都是:让 uv 管理 Python,而不是让 Python 管理 uv。


3. 依赖关系对比

维度standalonepip 安装
依赖 Python❌ 不依赖✅ 依赖特定 Python
依赖 site-packages❌ 不依赖✅ 装在 site-packages 中
与其他工具的关系同级独立工具附属于某个 Python 环境
依赖链Windows → uv.exeWindows → python.exe → site-packages → uv

4. 先有鸡还是先有蛋?

一台全新电脑,没有任何 Python:

  • standalone:下载 uv.exe → uv python install 3.13 → 完成
  • pip 安装:没有 Python → 没有 pip → 无法 pip install uv → 死锁

所以官方推荐:先装 standalone uv,再用 uv 管理 Python。

5. 更新方式的区别

standalonepip 安装
更新命令uv self updatepip install --upgrade uv
更新对象uv.exe 自身site-packages 中的 uv 包

standalone 的更新更直接,不经过 Python 包管理体系。


6. Windows 用户为什么更适合 standalone?

Windows 上 Python 多版本共存是常态(Python310/311/312/313,再加 Anaconda、Pyenv 等)。pip 安装会导致 PATH 中出现多个 uv.exe,where uv 输出一堆结果。而 standalone 的优势是 uv 自己独立于具体 Python 环境(始终只有一个 C:\Users\你的用户名\.local\bin\uv.exe 入口),不容易因为 Python 多版本共存而产生工具归属混乱。

7. 删除 Python 会发生什么?

场景standalonepip 安装
删除 Python 后uv 仍在,可继续使用uv 随 Python 一起消失
重新安装 Pythonuv python install 3.14 即可需先重装 Python,再重装 uv

8. 安装方式会影响包管理吗?—— 不会

这是最常见的误解。 uv 的安装方式与它管理项目包的方式基本无关。

1. 项目依赖管理

执行 uv add requests 时:修改 pyproject.toml → 更新 uv.lock → 安装到 .venv/Lib/site-packages(Windows)。在标准的 uv 项目工作流中,项目依赖会安装到项目自己的 .venv,不会直接污染系统 Python。

2. 全局工具

推荐用 uv tool install ruff 而非 pip install ruff。uv 为每个工具创建独立虚拟环境:

1
2
3
C:\Users\你的用户名\AppData\Roaming\uv\tools\
ruff\.venv\ ← ruff 专属环境
black\.venv\ ← black 专属环境

一个工具一个环境,互不污染。

3. 缓存机制

uv 有全局缓存:首次 uv add requests 下载并缓存,后续其他项目再用 requests 时直接复制到 .venv,无需重复下载。


9. 虚拟环境命名实践

虚拟环境本质上就是一个文件夹,里面放着独立的 Python 解释器和 site-packages。

1. 常见命名

名字常见程度说明
.venv⭐⭐⭐⭐⭐现在最推荐
venv⭐⭐⭐⭐也很常见
env⭐⭐⭐老项目较多

2. 为什么 .venv 成为事实标准?

  • 隐藏文件夹:以点开头默认隐藏,不干扰项目源码关注
  • 工具自动识别:uv、VS Code、PyCharm 默认优先检测 .venv
  • 避免混淆:不会与存放环境变量的 .env 文件冲突
  • 社区趋势:uv init、hatch new 等脚手架默认生成 .venv

3. uv venv 与 .venv 矛盾吗?—— 不矛盾

概念是什么
uv venv一条 命令,用于创建虚拟环境
.venv虚拟环境目录的 命名约定

uv venv 默认创建的就是 .venv 文件夹——命令是动作,.venv 是动作的默认结果。 也可以指定其他名字:uv venv my_env。两者是协作关系:uv venv 是推荐创建虚拟环境的工具,.venv 是推荐给虚拟环境的命名。


10. 综合对比总结

对比维度standalonepip 安装
官方推荐✅❌(可用但非首选)
不依赖 Python✅❌
能安装 Python✅⚠️ 可以,但依赖已有 Python
删除 Python 后还能用✅❌
更新方式uv self updatepip install -U uv
Windows 多 Python 环境✅ 最省心⚠️ 容易混乱
CI/CD 或容器✅ 常见也可,视镜像而定
功能与 pip 安装完全一致与 standalone 完全一致

11. 常用命令速查表

1. uv 项目管理(推荐新项目使用)

功能说明uv 命令pip 等价命令
查看版本uv --versionpip --version
创建项目(生成 pyproject.toml)uv init❌
创建虚拟环境uv venvpython -m venv .venv
激活虚拟环境(系统命令,与 uv/pip 无关).\.venv\Scripts\activate相同
安装依赖(uv 会更新 pyproject.toml 和 uv.lock)uv add requestspip install requests
安装指定版本uv add requests==2.32.0pip install requests==2.32.0
升级依赖uv add requests --upgrade-package requestspip install -U requests
删除依赖(uv 同步更新配置文件)uv remove requestspip uninstall requests
安装 requirementsuv add -r requirements.txtpip install -r requirements.txt
导出 requirementsuv export -o requirements.txtpip freeze > requirements.txt
查看已安装包uv pip listpip list
查看包信息uv pip show requestspip show requests
查看过期包uv pip list --outdatedpip list --outdated
检查依赖(检查依赖冲突)uv pip checkpip check
安装本地项目(可编辑模式)uv pip install -e .pip install -e .
同步依赖(根据 lock 文件创建一致环境)uv sync❌
锁定依赖(生成或更新 uv.lock)uv lock❌
运行脚本(自动使用项目虚拟环境)uv run main.pypython main.py
运行模块uv run -m pytestpython -m pytest
安装 Pythonuv python install 3.13❌
查看 Pythonuv python list❌
切换 Pythonuv python pin 3.13❌
安装全局工具(uv 为每个工具创建独立环境)uv tool install ruffpip install ruff(不推荐)
更新全局工具uv tool upgrade ruffpip install -U ruff
卸载全局工具uv tool uninstall ruffpip uninstall ruff
查看工具uv tool list❌
清理缓存uv cache cleanpip cache purge
查看缓存目录uv cache dirpip cache dir
更新 uvuv self update(standalone)pip install -U uv

2. uv pip、uv add 和 pip 的关系

先明确一个关键点:uv pip 和 uv 不是同一个层级的概念。 uv 是一个完整的 Python 项目管理工具,uv pip 只是它众多子命令中的一个:

1
2
3
4
5
6
7
8
9
uv
├── uv add
├── uv remove
├── uv sync
├── uv lock
├── uv run
├── uv tool
├── uv python
└── uv pip

正确的关系是:

1
2
uv
└── uv pip

而不是:

1
uv ≈ pip
命令实际执行者是否修改 pyproject.toml定位
pip install requestspip❌传统包管理
uv pip install requestsuv(Rust 实现)❌pip 的高性能替代
uv add requestsuv✅现代项目管理

三类工具定位:

工具定位常用命令
pip老牌包管理器install、uninstall、list、freeze
uv pippip 的高速替代uv pip install、uv pip list、uv pip show
uv现代 Python 项目管理器init、add、remove、sync、lock、run、tool、python

12. 小结

  1. 理解 uv 的性能优势:uv 加速的是 Python 工具链(依赖解析、安装、环境管理、部署流程),不是 Python 程序运行速度。
  2. 理解 Rust 的作用:Rust 重写的是 Python 包管理基础设施,而不是 numpy、pandas、requests 等 Python 库本身。
  3. 安装 uv:优先 standalone,尤其是 Windows 用户。
  4. 新项目:使用 uv init → uv add → uv run → uv sync 工作流。
  5. 老项目:如果只需要 requirements.txt 兼容,使用 uv pip ... 即可享受速度优势。
  6. 全局工具:用 uv tool install 替代 pip install,实现环境隔离。

uv 的安装方式只管 uv 自己怎么来,不管 uv 怎么管你的项目。