在 Python 工程里,依赖安装慢、虚拟环境割裂、pip 与 poetry 工具链不统一,几乎是每个团队都踩过的坑。uv 是 Astral(Ruff 背后的团队)用 Rust 打造的 Python 极速包管理器,官方基准显示比 pip 快 10–100 倍。一个二进制就能替代 pip、pip-tools、virtualenv、pipx,甚至部分 pyenv 的能力,同时还能管理整个项目的依赖锁定与可复现环境。本文从安装讲到工程化落地,帮你把依赖管理统一到 uv,彻底告别”装个包去泡杯咖啡”的等待,让本地开发与 CI 都进入秒级时代。
一、为什么需要 uv
传统 Python 依赖工具有一个共同痛点:pip 解析慢且不支持锁定文件,poetry 体验好但安装与解析依赖仍然偏慢,virtualenv、pipx、pyenv 又各自为政,新人入职光是配环境就要折腾半天。uv 用 Rust 重写后把这几件事收敛到一个二进制里,并且通过全局缓存、并行下载、直接读取 wheel 元数据做依赖解析,把安装和锁定速度提升了一个数量级。对动辄几百个依赖的数据科学和 Web 项目来说,这种差距在 CI 里尤其明显,一次构建往往能省下几分钟。
| 能力 | pip | poetry | uv |
|---|---|---|---|
| 安装依赖 | ✅ | ✅ | ✅(快 10–100×) |
| 锁定文件 (lock) | ❌(需 pip-tools) | ✅ | ✅ |
| 虚拟环境 | 需 virtualenv | 内置 | 内置 (uv venv) |
| Python 版本管理 | 需 pyenv | 部分 | ✅ (uv python) |
| CLI 工具隔离 | 需 pipx | ❌ | ✅ (uv tool) |
二、安装 uv
uv 是单文件二进制,安装方式很多。推荐用官方脚本或系统包管理器,CI 里则常直接下载二进制。装好后 uv 会出现在 PATH,可直接调用,后续升级也只需重新执行安装脚本。
# 官方安装脚本(macOS / Linux)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 用 pipx 隔离安装(不影响系统 Python)
pipx install uv
# macOS 用 Homebrew
brew install uv
# 验证
uv --version
三、作为 pip 的极速替代品
如果你只想把现有项目的 pip 换成更快的实现,uv pip 子命令几乎是零成本的 drop-in 替代。它复用你熟悉的命令结构,只是把速度换成了 Rust 级别。要注意它默认作用于当前虚拟环境,未激活环境时请先创建 venv,否则可能装到意想不到的位置。
# 创建虚拟环境
uv venv
# 安装依赖(等价 pip install)
uv pip install "fastapi[standard]" pydantic
# 从 requirements.txt 安装
uv pip install -r requirements.txt
# 编译锁定(等价 pip-compile)
uv pip compile requirements.in -o requirements.txt
# 精确同步(等价 pip-sync,保证环境与锁文件一致)
uv pip sync requirements.txt
# 导出当前环境
uv pip freeze
| pip 命令 | uv 等价命令 |
|---|---|
| python -m venv .venv | uv venv |
| pip install pkg | uv pip install pkg |
| pip install -r req.txt | uv pip install -r req.txt |
| pip-compile | uv pip compile |
| pip-sync | uv pip sync |
四、用 uv 管理完整项目(pyproject.toml)
uv 不止是 pip 替代品,它还能像 poetry 一样管理整个项目。一条 uv init 会生成 pyproject.toml,uv add 自动写依赖并生成 uv.lock,uv sync 重建可复现环境。整个过程不再需要记忆多个工具的命令,新人照着命令敲就能跑起来。
# 初始化项目
uv init myproj && cd myproj
# 添加运行时依赖(自动写入 pyproject + 更新 uv.lock)
uv add fastapi
# 添加开发依赖
uv add --dev pytest ruff
# 解析并锁定全部依赖
uv lock
# 按 uv.lock 精确同步环境
uv sync
# 在隔离环境里运行脚本
uv run main.py
生成的 pyproject.toml 遵循标准 [project] 表,uv.lock 则是跨平台可复现的锁定文件,提交到 Git 后即可保证团队与 CI 环境一致。想了解 Python Web 服务的工程写法,可参考本站 FastAPI 生产级异步接口实战。
五、PEP 723 内联脚本元数据
uv 支持 PEP 723 内联脚本元数据,让你在单个 .py 文件顶部声明依赖,uv run 会自动创建临时环境并安装,非常适合一次性脚本和 Notebook 工具。脚本自带依赖声明后,分享给别人也能一键跑通,不再出现”在我机器上是好的”这类问题。
# /// script
# requires-python = ">=3.11"
# dependencies = ["requests", "rich"]
# ///
import requests
from rich import print
resp = requests.get("https://api.github.com/zen")
print(f"[green]zen:[/green] {resp.text}")
六、Docker 多阶段构建集成
在容器里用 uv 可以显著缩小镜像并加速构建。关键点:先拷贝 pyproject.toml 与 uv.lock,再用 uv sync --frozen 精确还原,最后只把依赖拷进运行阶段。这样镜像里不含构建工具,也更利于层缓存。容器化思路可结合本站 Docker 实战:从镜像到容器编排 一起看。
FROM python:3.12-slim AS builder
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
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY . .
ENV PATH="/app/.venv/bin:$PATH"
CMD ["python", "main.py"]
七、GitHub Actions 持续集成
CI 里用 astral-sh/setup-uv 动作即可一键装好 uv,再用 uv python install 与 uv sync 重建环境,比缓存 pip 更快更稳。配合 uv.lock 的 –locked 校验,还能防止有人忘记更新锁文件就提交代码。完整流水线编排可参考 GitHub Actions 自动化构建与部署。
name: ci
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv python install 3.12
- run: uv sync --locked
- run: uv run pytest
八、迁移清单与常见坑
| 场景 | 建议 |
|---|---|
| 老项目用 requirements.txt | uv pip compile 生成锁文件后切 uv pip sync |
| 老项目用 poetry | uv init 后 uv add 逐条迁移,删 poetry.lock |
| 需系统级安装 | uv pip install –system(容器里常见) |
| 团队环境不一致 | 提交 uv.lock,统一用 uv sync –frozen |
常见坑:第一,uv pip install 默认操作当前虚拟环境,未激活环境时会装到哪儿取决于 UV_PROJECT_ENVIRONMENT,建议先 uv venv 再操作;第二,uv sync 会移除锁文件里没有的包,属于”精确还原”,和 pip install 的累加语义不同,迁移期别混用;第三,内联脚本(PEP 723)的依赖不会写进 pyproject,仅靠 uv run 临时环境。更多现代命令行工具的组合用法见 现代 CLI 工具:eza/zoxide/bat 提效实践。
九、uv tool:用一条命令管理 CLI 工具
过去装 ruff、black 这类命令行工具要用 pipx,现在 uv 内置了 uv tool 子命令,同样能做隔离安装与升级,少装一个工具就是少一份心智负担。它和 uv 本身共用一套缓存,安装速度同样很快。
# 隔离安装 CLI 工具
uv tool install ruff
# 查看已安装工具
uv tool list
# 升级单个工具
uv tool upgrade ruff
# 免安装临时运行(等价 pipx run)
uvx ruff check .
十、uv python:一行管理多版本解释器
uv 还内置了 Python 解释器管理,能自动下载并切换多个版本,基本可以替代 pyenv。解释器被放进 uv 自己的目录,不污染系统;项目里用 uv python pin 固定版本后,团队成员和 CI 拉下来的就是同一份。
# 安装指定版本解释器(自动下载到 uv 目录)
uv python install 3.13
# 列出本机可用解释器
uv python list
# 在当前项目固定版本
uv python pin 3.12
# 临时用其他版本跑脚本
uv run --python 3.11 main.py
十一、全局缓存与性能内幕
uv 快的核心在于全局内容寻址缓存(默认在 ~/.cache/uv):同一个 wheel 无论被多少项目引用都只下载一次,解析阶段直接读 wheel 元数据而非解压,再配合 Rust 的并行 IO,所以首次安装就已显著快于 pip,重复安装几乎秒回。CI 里把该缓存目录持久化,就能跨任务复用,进一步压缩构建时间;本地多项目共享同一份缓存,磁盘占用也更省。理解这一点后,你会发现 uv 的”快”并非玄学,而是工程上的必然。
| 维度 | pip | uv |
|---|---|---|
| 缓存粒度 | 按包名 | 内容寻址(去重更彻底) |
| 解析方式 | 串行 | 并行读取元数据 |
| 跨项目复用 | 有限 | 全局共享,一次下载多次用 |
十二、小结
uv 用 Rust 把 Python 依赖管理的速度和一致性拉到了新高度:小到替换 pip、管理 CLI 工具与多版本解释器,大到统一管理项目与 CI,都能用同一套命令完成。对新项目直接 uv init 起步,对老项目从 uv pip compile/sync 平滑迁移,是性价比最高的路径。当依赖安装不再是等待,你的迭代节奏会明显变轻,团队也能把精力放回真正重要的业务代码上。




