为什么需要uv?
Python的包管理一直是开发者的痛点。pip速度慢、依赖冲突难排查、虚拟环境管理繁琐、poetry和pipenv各有一套生态。2024年,Astral团队(ruff的作者)发布了uv——一个用Rust编写的Python包管理工具,目标是一统江湖。
uv的核心优势:
- 快:比pip快10-100倍(基于Rust + 并行下载 + 全局缓存)
- 全:替代pip、pip-tools、pipx、poetry、pyenv、virtualenv
- 兼容:完全兼容pip的依赖格式、pyproject.toml、requirements.txt
- 可靠:确定性构建,lock文件保证环境一致性
安装uv
1
2
3
4
5
6
7
8
|
# 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"
# 或者通过pip安装
pip install uv
|
安装完成后验证:
1
2
|
uv --version
# uv 0.x.x (xxxx-xx-xx)
|
核心命令速查
uv的命令设计非常直觉,几乎和pip一一对应:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 安装包(替代 pip install)
uv pip install requests
uv pip install "django>=4.2,<5.0"
# 卸载包
uv pip uninstall requests
# 列出已安装包
uv pip list
# 生成依赖文件
uv pip freeze > requirements.txt
# 从文件安装
uv pip install -r requirements.txt
|
速度对比实测:
1
2
3
4
5
6
7
|
# pip 安装 requests(含依赖)
time pip install requests
# 约 3-5 秒
# uv 安装同样的包
time uv pip install requests
# 约 0.2-0.5 秒
|
项目级依赖管理
uv真正强大的地方在于项目级管理,这也是它替代poetry的核心场景。
初始化项目
1
2
3
4
5
6
7
8
9
10
|
# 创建新项目(自动生成 pyproject.toml)
uv init my-project
cd my-project
# 项目结构
my-project/
├── pyproject.toml
├── README.md
├── hello.py
└── .python-version
|
pyproject.toml 内容:
1
2
3
4
5
6
7
|
[project]
name = "my-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
|
添加依赖
1
2
3
4
5
6
7
8
9
10
|
# 添加运行时依赖(替代 poetry add)
uv add requests
uv add "fastapi>=0.100"
uv add "sqlalchemy[asyncio]" # 带额外依赖
# 添加开发依赖
uv add --dev pytest ruff mypy
# 添加可选依赖组
uv add --optional extra --group docs mkdocs
|
添加后 pyproject.toml 自动更新:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"requests>=2.31",
"fastapi>=0.100",
"sqlalchemy[asyncio]>=2.0",
]
[dependency-groups]
dev = [
"pytest>=8.0",
"ruff>=0.4",
"mypy>=1.10",
]
[project.optional-dependencies]
extra = []
docs = [
"mkdocs>=1.6",
]
|
锁文件与确定性构建
1
2
3
4
5
6
7
8
9
10
11
|
# 生成 lock 文件(替代 poetry.lock)
uv lock
# 从 lock 文件安装(CI/CD 场景)
uv sync
# 仅安装生产依赖(不含 dev)
uv sync --no-dev
# 安装特定依赖组
uv sync --group docs
|
uv.lock 文件确保团队成员和CI环境安装完全一致的依赖版本。
运行脚本
1
2
3
4
5
6
7
|
# 在项目虚拟环境中运行
uv run python hello.py
uv run pytest
uv run ruff check .
# 运行项目入口
uv run my-project
|
虚拟环境管理
uv内置虚拟环境管理,无需额外工具:
1
2
3
4
5
6
7
8
9
10
11
|
# 创建虚拟环境
uv venv
# 指定Python版本创建
uv venv --python 3.12
# 激活(标准方式)
source .venv/bin/activate
# uv也能自动管理,通常不需要手动激活
# uv run 会自动使用 .venv
|
Python版本管理
uv还可以管理Python版本本身,替代pyenv:
1
2
3
4
5
6
7
8
9
10
11
12
|
# 安装特定Python版本
uv python install 3.12
uv python install 3.13
# 列出已安装版本
uv python list
# 为项目指定Python版本
uv python pin 3.12
# 自动下载项目所需的Python版本
uv python install
|
.python-version 文件内容:
工具安装(替代pipx)
1
2
3
4
5
6
7
8
9
10
11
12
|
# 安装全局CLI工具
uv tool install ruff
uv tool install black
uv tool install httpie
# 运行工具(无需安装)
uvx ruff check .
uvx black --check .
uvx httpie GET https://httpbin.org/get
# 列出已安装工具
uv tool list
|
迁移指南
从pip迁移
1
2
3
4
5
6
|
# 已有 requirements.txt,直接用uv安装
uv pip install -r requirements.txt
# 或者迁移到 uv 的项目管理
uv init
uv add -r requirements.txt
|
从poetry迁移
1
2
3
4
5
6
7
8
|
# 1. 初始化uv项目
uv init my-project
# 2. 从pyproject.toml导入依赖(uv兼容poetry的pyproject.toml格式)
uv add $(poetry show | awk '{print $1}')
# 3. 或者手动迁移:将poetry的pyproject.toml中[tool.poetry.dependencies]的内容
# 移到[project] dependencies,格式从 poetry 风格改为 PEP 621 标准
|
poetry 格式 → PEP 621 格式对照:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# Poetry 风格
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.31"
django = {version = "^4.2", optional = true}
# PEP 621 标准(uv使用)
[project]
requires-python = ">=3.12"
dependencies = [
"requests>=2.31",
]
[project.optional-dependencies]
django = ["django>=4.2"]
|
实战:搭建一个FastAPI项目
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# 1. 创建项目
uv init fastapi-demo
cd fastapi-demo
# 2. 添加依赖
uv add fastapi uvicorn[standard] pydantic
# 3. 创建主入口
cat > main.py << 'EOF'
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
in_stock: bool = True
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.post("/items/")
def create_item(item: Item):
return {"item": item.model_dump(), "status": "created"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
EOF
# 4. 运行
uv run uvicorn main:app --reload
|
访问 http://127.0.0.1:8000/docs 即可看到Swagger文档。
CI/CD集成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# GitHub Actions 示例
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
with:
version: "latest"
- run: uv sync --no-dev
- run: uv run pytest
- run: uv run ruff check .
|
astral-sh/setup-uv action 会自动缓存依赖,CI速度显著提升。
配置与技巧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# uv.toml 全局配置
[tool.uv]
# 使用镜像源(国内加速)
[[tool.uv.index]]
url = "https://mirrors.aliyun.com/pypi/simple/"
default = true
# 或者用官方源 + 镜像fallback
[[tool.uv.index]]
url = "https://pypi.org/simple/"
[[tool.uv.index]]
url = "https://mirrors.aliyun.com/pypi/simple/"
name = "aliyun"
|
1
2
3
4
5
6
7
8
9
10
11
|
# 设置代理(国内网络环境)
export UV_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
# 查看依赖树
uv tree
# 仅查看直接依赖
uv tree --depth 1
# 编译依赖(生成精确版本的 requirements 文件)
uv pip compile pyproject.toml -o requirements.txt
|
总结
uv是目前Python生态中最快的包管理工具,没有之一。它用一个工具替代了pip、pipenv、poetry、pyenv、virtualenv、pipx,而且速度提升了一个数量级。
关键决策点:
- 新项目:直接用
uv init 开始
- 存量项目:从
uv pip install -r requirements.txt 逐步迁移
- 团队协作:用
uv.lock 锁定依赖版本
- CI/CD:用
astral-sh/setup-uv action + uv sync
- 国内网络:配置阿里云镜像源
2026年,如果你还在用pip手动管理依赖,是时候试试uv了。