前言:你的时间正在被 pip 悄悄浪费
先做个小测试。新建一个虚拟环境,装一个 fastapi:
bash
python -m venv .venv && .venv/Scripts/activate
pip install fastapi
在 2026 年的今天,这仍然可能要等 30 秒以上。pip 会先做一次全量依赖解析,再一个一个地下载 wheel,最后逐个安装。如果 requirements.txt 里有几十个包,或者你每天要在多个项目间切换、反复重建环境,浪费的时间就非常可观了。
uv 就是冲着这个问题来的。它是 Astral 公司(对,就是做 Ruff 的那家)用 Rust 写的 Python 包管理器和解析器,号称比 pip 快 10~100 倍。本文不吹概念,直接给你一套从「看懂它」到「在团队里落地」的完整路径,所有命令都经过验证。
一、uv 为什么能快这么多
快不是玄学,主要来自四个设计:
- Rust 实现:下载、解压、安装全链路没有 Python 解释器参与,省掉了大量 Python 层开销;
- 全局内容寻址缓存 :所有下载过的 wheel 存在一个全局缓存里(Linux/macOS 在
~/.cache/uv,Windows 在%LOCALAPPDATA%\uv\cache),新项目安装时通过硬链接直接复用,而不是重新复制; - 并发下载:同时拉取所有依赖,而不是像 pip 那样逐个排队;
- 更聪明的解析器:基于 PubGrub 算法(Cargo 同款),一次解析出完整依赖图,锁定精确版本。
同样的依赖,pip 需要 30 秒,uv 通常 1~2 秒内完成------第一次要下包,之后几乎是瞬间。
二、安装 uv(三条路任选)
bash
# 方式一:pip 安装(最省事)
pip install uv
# 方式二:官方脚本(macOS / Linux)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 方式三:Windows PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
包管理器用户:winget install astral-sh.uv、scoop install uv、brew install uv 也都支持。
装完验证:
bash
uv --version
三、先忘掉复杂概念:最常用的三个命令
uv 的定位是「全家桶」,但日常 90% 的场景只需要三个命令:
1. uv venv ------ 创建虚拟环境
bash
cd myproject
uv venv
# 输出:Using Python 3.12.7
# Creating virtual environment at: .venv
如果本机没有合适的 Python 版本,uv 会自动下载一个(见第五节),完全不需要手动装。
2. uv pip install ------ 兼容 pip 的安装命令
bash
uv pip install -r requirements.txt
uv pip install fastapi "pydantic>=2.0" pytest --dev
它兼容 pip 的参数习惯,旧项目可以直接切换。
3. uv run ------ 一键执行
bash
uv run python main.py
# 或直接执行脚本
uv run main.py
uv run 会自动激活当前目录的 .venv 并运行命令,不需要手动 source activate。
四、从 requirements.txt 迁移到 uv.lock
临时项目用 uv pip install 就够了;长期维护的项目建议直接上 pyproject.toml + uv.lock,这才是 uv 的真正威力。
4.1 初始化项目
bash
uv init myapp
cd myapp
这会生成:
bash
myapp/
├── .python-version # 记录 Python 版本
├── pyproject.toml # 项目元数据 + 依赖声明
├── main.py
└── README.md
4.2 添加依赖
bash
uv add fastapi "uvicorn[standard]" httpx
uv add 会做两件事:把依赖写进 pyproject.toml 的 [project.dependencies],同时生成/更新 uv.lock 锁定精确版本。
4.3 同步安装(对应 pip 的 install)
bash
uv sync
uv sync 严格按照 uv.lock 安装,保证团队每个人、每台 CI 机器拿到的依赖字节级一致。新增成员克隆仓库后只需要两步:
bash
uv sync
uv run python main.py
4.4 升级依赖
bash
uv lock --upgrade # 重新解析并升级 lock 文件
uv lock --upgrade-package fastapi # 只升级某个包
4.5 已有 requirements.txt 怎么办?
bash
# 自动把 requirements.txt 的内容迁移到 pyproject.toml
uv add -r requirements.txt
之后删掉 requirements.txt,统一走 pyproject.toml。
五、Python 版本管理(替代 pyenv)
uv 内置了 Python 版本管理,再也不用装 pyenv:
bash
# 安装指定版本
uv python install 3.12
uv python install 3.11.9
# 查看可用版本
uv python list
# 为当前项目固定版本(写入 .python-version)
uv python pin 3.12
项目目录下有了 .python-version 后,uv venv、uv run 都会自动使用对应版本。在 2026 年,新机器配 Python 环境只需要一个 uv。
六、uvx:跑一次性工具
uvx(uv 的孪生命令)用于执行临时工具,装完即用、用完即走,不污染环境:
bash
# 直接运行 ruff 检查代码
uvx ruff check .
# 起一个本地 HTTP 服务
uvx serve .
# 运行其他语言工具
uvx yamllint config.yml
原理:工具被缓存到全局,重复运行秒开。CI 里特别适合------不用预先 pip install 工具链。
七、在 CI / Docker 里落地
GitHub Actions
yaml
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true # 缓存 uv 依赖,CI 提速明显
- run: uv sync --frozen # --frozen: 严格按 lock 安装,lock 过期直接报错
- run: uv run pytest
Dockerfile
dockerfile
FROM python:3.12-slim
# 安装 uv(官方镜像推荐方式)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-install-project
COPY . .
CMD ["uv", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0"]
关键点:先拷贝 pyproject.toml 和 uv.lock 再 uv sync,可以充分利用 Docker 层缓存------依赖没变时这一层不会重建。
八、国内网络与私有源配置
uv 支持环境变量和配置文件(pyproject.toml 或 uv.toml):
bash
# 临时指定镜像源
uv pip install -i https://pypi.tuna.tsinghua.edu.cn/simple
# 或写入环境变量,长期生效
export UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
私有仓库(如公司 Nexus / Artifactory):
toml
# uv.toml
[[index]]
url = "https://pypi.org/simple"
[[index]]
url = "https://nexus.example.com/repository/pypi/simple"
priority = "primary"
九、三个容易踩的坑
坑 1:把 uv pip install 和 uv add 混着用
一个项目里如果两种方式都用了,pyproject.toml 和实际环境可能不一致。新项目只用 uv add / uv sync;临时环境才用 uv pip install。
坑 2:在 CI 里忘加 --frozen
不加 --frozen 时,uv sync 在 lock 文件过期时会自动重新解析 ,导致 CI 装的版本和本地不一致。生产流程一律加 --frozen,让「锁文件过期」直接变成构建错误,倒逼开发者及时更新。
坑 3:以为 uv 会自己找 Python
uv venv 在系统没有合适 Python 时会自动下载,但如果系统里恰好有一个旧版本 (比如 3.9),它会「尊重」旧版本而不是自动升级。项目里用 uv python pin 3.12 显式固定,避免同事的机器环境不一致。
十、命令对照速查表
| 场景 | pip 时代 | uv 时代 |
|---|---|---|
| 创建环境 | python -m venv .venv |
uv venv |
| 安装依赖 | pip install -r requirements.txt |
uv sync(有 lock)/ uv pip install -r requirements.txt |
| 添加依赖 | pip install fastapi && pip freeze > requirements.txt |
uv add fastapi |
| 移除依赖 | 手动改 requirements.txt | uv remove fastapi |
| 运行脚本 | source .venv/bin/activate && python main.py |
uv run python main.py |
| 管理 Python 版本 | 装 pyenv | uv python install / pin |
| 一次性工具 | pip install ruff && ruff check . |
uvx ruff check . |
结语
uv 最聪明的地方在于学习成本趋近于零 :uv pip install 完全兼容 pip 的肌肉记忆,而 uv add / uv sync / uv.lock 又提供了现代包管理器该有的可复现性。它没有发明新概念,只是把「依赖解析 + 下载 + 安装 + 版本管理」这些苦活全部重做了一遍。
建议迁移节奏:第一周 ,把个人项目的 pip install 换成 uv pip install(零成本);第一个月 ,新项目直接用 uv init,走 uv add / uv sync 流程;一个季度内,把团队 CI 和 Dockerfile 切到 uv,你会看到构建时间肉眼可见地缩短。
如果你的团队还在争论「用 pip 还是 poetry」------别争了,试试 uv,答案会自己浮现。