先说一个你可能经历过的场景:克隆了一个老项目,根目录躺着 requirements.txt,你 pip install -r requirements.txt 然后盯着终端发呆——解析依赖两分钟,下载安装五分钟,最后还报一行红色的 ERROR: Cannot install X and Y because they have incompatible versions。你加了个新依赖,Poetry 解析锁文件花了半分钟;团队三个人,三个人装出来的子依赖版本都不一样,"我这能跑啊"成了每日站会的固定台词。
这不是你网络差,是工具链老了。2024 年,做 Ruff 的那个团队 Astral 用 Rust 写了个新工具叫 uv,定位就是"一个替代 pip、virtualenv、pip-tools、poetry、pyenv、pipx 的一站式工具"。官方基准测试里,它装依赖比 pip 快 10~100 倍,热缓存场景下甚至能到 80~115 倍;第三方实测里,装 Django+Celery+Pandas+scikit-learn 这套组合,pip 要 90 秒,Poetry 50 秒,uv 只要 8 秒。我用了一年,现在新建项目连 python -m venv 都不敲了。这篇文章把安装、核心工作流、迁移和避坑一次讲完。
一、先建立认知:uv 快在哪,它到底替代了谁
uv 不是"更快的 pip",它是一套重新设计的工具链,快的原因有三个:
它替代的不是一个工具,而是一整排:pip(包安装)、venv/virtualenv(虚拟环境)、pip-tools(依赖锁定)、poetry/pdm(项目管理)、pyenv(Python 版本管理)、pipx(全局工具隔离)。
二、安装:一行命令,全平台通用
bash
编辑
1# macOS / Linux
2curl -LsSf https://astral.sh/uv/install.sh | sh
3
4# Windows PowerShell
5powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
6
7# 验证
8uv –version
装完必须重启终端,不然 PATH 不生效,你会看到经典的"'uv' 不是内部或外部命令"——这不是装失败了,是环境变量没刷新。国内用户第一步先配镜像源,不然解析 PyPI 慢到让你以为 uv 名不副实:
bash
编辑
1# 临时生效
2export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
3
4# 持久化:~/.config/uv/uv.toml(Windows 在 %APPDATA%\\uv\\uv.toml)
5
6[[index]]
7url = "https://pypi.tuna.tsinghua.edu.cn/simple"
8default = true
三、核心工作流:从零到项目跑起来
1. 初始化项目——五条命令走完传统工具链半天的活
bash
编辑
1uv init my_project # 生成 pyproject.toml、README.md、.gitignore、main.py
2cd my_project
3uv python install 3.12 # uv 自己管理 Python 版本,告别 pyenv
4uv python pin 3.12 # 项目级固定版本,生成 .python-version
5uv add fastapi uvicorn # 加生产依赖,自动写 pyproject.toml 并更新锁文件
6uv add –dev pytest ruff # 加开发依赖
7uv run uvicorn main:app # 直接跑,自动识别虚拟环境,无需手动激活
uv run 是我每天用最多的子命令:它自动创建 .venv、自动按锁文件装好依赖、在隔离环境里执行命令。你再也用不到 source .venv/bin/activate 了。
2. 项目文件该提交什么
表格
下载为表格
导出为图片
| pyproject.toml | 依赖声明(我要什么) | ✅ 是 |
| uv.lock | 锁文件(实际装了什么) | ✅ 是 |
| .python-version | 项目 Python 版本 | ✅ 建议是 |
| .venv/ | 虚拟环境 | ❌ 否 |
uv.lock 必须进版本控制——它是"任何机器 uv sync –frozen 都能复现环境"的保证。
3. 日常高频命令
bash
编辑
1uv sync # 按锁文件同步环境(克隆项目后第一条跑它)
2uv lock # 只更新锁文件不安装
3uv add "requests>=2.31" # 指定版本约束
4uv remove requests # 移除依赖
5uv tree # 查看依赖树,排查冲突神器
6uv run pytest # 跑测试
7uvx ruff check . # 临时跑个 CLI 工具,不污染项目(类似 pipx run)
4. 老项目迁移:不用一步到位
uv 对老工作流完全兼容,可以渐进迁移:
bash
编辑
1# 方案A:直接吃 requirements.txt
2uv venv
3uv pip install -r requirements.txt
4
5# 方案B:把 requirements.txt 升级成现代项目管理
6uv add -r requirements.txt # 依赖迁入 pyproject.toml
7uv lock # 生成锁文件
uv pip 子命令和 pip 语义一致,-r、–index-url 等参数全支持,现有 CI 脚本改一个词就能用。
四、避坑指南:这四条是我真金白银换来的
坑一:换了 Python 版本不删 .venv。 uv 不支持原地升级解释器——uv python pin 3.13 之后必须 rm -rf .venv && uv venv –python 3.13,否则你会看到一堆令人费解的导入错误。换版本必删环境,这是铁律。
坑二:CI 里用 uv sync 裸跑。 裸 uv sync 允许更新锁文件,CI 上应该用 uv sync –frozen——锁文件需要改就报错,保证 CI 装的和本地锁的比特级一致。生产镜像里再加 –no-dev 只装运行依赖。
坑三:和 Conda 的关系没摆正。 uv 不管 Conda 环境本身,正确姿势是"Conda 管 CUDA/底层库底座,uv 管 Python 包"——激活 Conda 环境后在里面 uv add / uv sync,两者不冲突。
坑四:全局缓存膨胀。 uv 所有项目共享一个缓存目录,日久天大会占几十 GB。定期 uv cache prune 清理未被引用的条目,磁盘告急时 uv cache clean 全清(下次装依赖会慢一次,仅此而已)。
五、适用边界:别什么项目都上
- 新项目、团队协作项目:无脑选 uv,pyproject.toml + uv.lock 是 2026 年的事实标准,生态头部项目已在采用;
- 老项目:先用 uv pip install -r 吃现有文件享受速度红利,有空再迁项目管理模式,迁移成本几乎为零;
- 纯一次性脚本:uv run –with requests script.py 一条命令搞定,连项目都不用初始化——这是 uv 最被低估的用法;
- 企业内网/私有 PyPI:uv add mypkg –index-url https://your-pypi/simple 直接支持,但注意 uv 目前不处理 Conda 那类非 Python 依赖,涉及 CUDA 的深度学习环境老老实实 Conda 打底。
一句话总结:pip 解决了"能不能装",uv 解决的是"装得快不快、复现得了复现不了"。后者才是工程问题。
你的项目依赖安装要多久?uv sync 之后省了多少时间?欢迎在评论区晒数据。
