2024-2025 年 Python 工具链经历了革命性更新:
uv以 Rust 编写,替代 pip + virtualenv + poetry 的组合;ruff统一了 flake8 + black + isort 的功能。本文提供「一步到位」的现代化迁移方案。
1. uv:一站式 Python 包管理器
1.1 为什么选 uv
| 工具 | 安装速度 | 虚拟环境 | Python 版本 | 依赖锁定 |
|---|---|---|---|---|
| pip | 慢(逐包下载) | 需 virtualenv | 无 | requirements.txt |
| poetry | 中等 | 内置 | 无 | poetry.lock |
| uv | 极速(并行+缓存) | 内置 | 内置 | uv.lock |
uv 由 Astral 团队(Rust 编写)开发,使命是替代 Python 工具链的「瑞士军刀」:
# 安装 uv(一行命令)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 验证
uv --version
1.2 核心命令速查
# ========== Python 版本管理 ==========
# 安装/切换 Python
uv python install 3.12
uv python install 3.11 3.10 # 多版本共存
# 查看已安装
uv python list
# ========== 虚拟环境 ==========
# 创建(.venv 目录)
uv venv
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
# 创建指定 Python 版本
uv venv --python 3.11
# ========== 包管理 ==========
# 安装(自动创建 venv、解析依赖)
uv pip install fastapi uvicorn
# 从 pyproject.toml 安装
uv pip install -e .
# 导出 lock 文件
uv pip compile pyproject.toml -o requirements.txt
# 从 lock 安装(确定性)
uv pip sync requirements.txt
# ========== 运行脚本 ==========
# 不需要激活 venv 即可运行
uv run python script.py
uv run pytest
uv run mypy src/
# 临时依赖(不需要写 pyproject.toml)
uv run --with pandas python analyze.py
1.3 项目初始化与依赖管理
# 初始化项目(生成 pyproject.toml)
uv init my-project
cd my-project
# 添加依赖
uv add fastapi uvicorn pydantic
uv add --dev pytest mypy ruff
# 添加可选依赖组
uv add --optional ml torch transformers
# 同步安装(严格按 lock 文件)
uv sync
# 运行
uv run fastapi dev main.py
生成的 uv.lock 示例片段:
version = 1
requires-python = ">=3.11"
[[package]]
name = "fastapi"
version = "0.111.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pydantic" },
{ name = "starlette" },
]
2. ruff:一个工具替代所有 Linter 和 Formatter
2.1 ruff 能力矩阵
ruff 以 Python 的 10-100 倍速度执行:
| 被替代工具 | 功能 | ruff 规则前缀 |
|---|---|---|
| black | 代码格式化 | 内置(无前缀) |
| isort | import 排序 | I |
| flake8 | 代码风格检查 | E, W, F |
| pyupgrade | Python 升级 | UP |
| pydocstyle | 文档字符串 | D |
| bandit | 安全检查 | S |
| mccabe | 复杂度 | C901 |
| pep8-naming | 命名规范 | N |
2.2 配置与使用
# 安装
uv add --dev ruff
# 检查代码
uv run ruff check src/
# 自动修复
uv run ruff check --fix src/
# 格式化代码
uv run ruff format src/
# 检查 + 格式化流水线
uv run ruff check --fix src/ && uv run ruff format src/
2.3 完整 pyproject.toml 配置
[tool.ruff]
target-version = "py311" # 目标 Python 版本
line-length = 100
[tool.ruff.lint]
select = [
"E", # pycodestyle 错误
"W", # pycodestyle 警告
"F", # Pyflakes
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"SIM", # flake8-simplify
"D", # pydocstyle
"S", # bandit(安全)
]
ignore = ["D104", "D100"] # 忽略某些规则
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S"] # 测试文件忽略安全规则
"__init__.py" = ["F401"] # 忽略未使用 import
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
3. 类型检查:mypy vs pyright
3.1 配置与运行
# pyproject.toml
[tool.mypy]
python_version = "3.11"
strict = true
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
ignore_missing_imports = true
show_error_codes = true
# 排除
exclude = [
"tests/",
"build/",
]
uv add --dev mypy
uv run mypy src/
3.2 CI 集成
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v2
- name: Install dependencies
run: uv sync
- name: Lint
run: uv run ruff check --output-format=github src/
- name: Type check
run: uv run mypy src/
- name: Test
run: uv run pytest
4. pipx:隔离安装 CLI 工具
# 用 pipx 安装全局 CLI 工具(不污染系统 Python)
pipx install poetry
pipx install black # 旧项目需要
pipx install poetry
pipx install pre-commit
# 一次性运行(不安装)
pipx run poetry --version
5. Hatch / Poetry / PDM:项目管理对比
| 工具 | 成熟度 | 虚拟环境 | 插件 | 推荐度 |
|---|---|---|---|---|
| Hatch | 高(PyPA 官方) | 内置 | 丰富 | ⭐⭐⭐⭐⭐ |
| Poetry | 极高 | 内置 | 多 | ⭐⭐⭐⭐ |
| PDM | 中高 | 可选 | PEP 582 | ⭐⭐⭐ |
| uv | 快速迭代 | 内置 | 少 | ⭐⭐⭐⭐⭐ (未来) |
5.1 Hatch 配置示例
[project]
name = "my-project"
dynamic = ["version"]
dependencies = ["fastapi", "uvicorn"]
[project.optional-dependencies]
dev = ["pytest", "mypy", "ruff"]
[tool.hatch.version]
path = "src/my_project/__init__.py"
[tool.hatch.envs.default]
dependencies = ["pytest", "mypy"]
[tool.hatch.envs.default.scripts]
test = "pytest {args}"
lint = "ruff check --fix src/ && ruff format src/"
6. 从 pip 到 uv 的迁移路径
6.1 逐步迁移步骤
# Step 1: 安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Step 2: 从 requirements.txt 导入
uv pip install -r requirements.txt
# Step 3: 初始化 pyproject.toml
uv init
# Step 4: 添加现有依赖到 pyproject.toml
# 手动编辑或使用 uv add $(cat requirements.txt)
# Step 5: 替换 Makefile/脚本中的命令
# pip install → uv pip install
# python -m pytest → uv run pytest
# source .venv/bin/activate → uv run (无需激活)
# Step 6: 生成 lock 文件
uv pip compile pyproject.toml -o requirements.lock
# Step 7: CI/CD 更新
# actions/setup-python → astral-sh/setup-uv
6.2 pyproject.toml 完整模板
[project]
name = "my-project"
version = "0.1.0"
description = "A modern Python project"
authors = [{ name = "Your Name", email = "you@example.com" }]
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.111",
"uvicorn[standard]>=0.30",
"pydantic>=2.7",
"sqlalchemy>=2.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
"mypy>=1.10",
"ruff>=0.4",
"pre-commit>=3.7",
]
ml = [
"torch>=2.3",
"transformers>=4.40",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.ruff]
target-version = "py311"
line-length = 100
[tool.ruff.lint]
select = ["E", "W", "F", "I", "N", "UP", "B", "C4", "SIM", "D"]
ignore = ["D100", "D104"]
[tool.mypy]
python_version = "3.11"
strict = true
ignore_missing_imports = true
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
7. 完整开发工作流
# 1. 克隆项目
git clone <repo>
cd my-project
# 2. 一键安装(uv 自动创建 venv)
uv sync
# 3. 代码检查 + 格式化 + 类型检查(pre-commit 钩子)
uv run ruff check --fix src/
uv run ruff format src/
uv run mypy src/
# 4. 运行测试
uv run pytest -xvs
# 5. 运行应用
uv run uvicorn app.main:app --reload
# 6. 添加新依赖
uv add httpx
uv add --dev types-requests
8. 工具链对比与选型
不同场景下的工具组合选择:
| 场景 | 推荐工具链 | 原因 |
|---|---|---|
| 个人脚本 | uv + ruff | 极简,一键运行 |
| 中小型项目 | uv + ruff + mypy | 现代、快速、低维护 |
| 大型项目 / 团队 | uv + ruff + mypy + pre-commit | 代码质量门禁 |
| 数据科学 | uv + ruff + jupyter | 环境隔离,依赖管理 |
| 遗留项目迁移 | 逐步替换:pip → uv,flake8/black → ruff | 渐进式升级 |
迁移注意事项
- lock 文件差异:uv 使用
uv.lock,与 poetry.lock / pdm.lock 不兼容,迁移时需重新生成 - 版本解析器:uv 的依赖解析可能与 poetry 略有差异,迁移后需验证
- editable 安装:uv 的
-e .行为与 pip 一致,但 hatch/poetry 可能使用不同目录结构 - 缓存清理:工具切换时清理 pip 缓存,避免旧包干扰
9. 性能基准对比
| 操作 | pip (s) | poetry (s) | uv (s) | 加速比 |
|---|---|---|---|---|
| 安装 fastapi(无缓存) | 12.5 | 8.3 | 1.2 | 10x |
| 安装 fastapi(有缓存) | 4.2 | 2.8 | 0.3 | 14x |
| 解析依赖树 | 8.5 | 5.2 | 0.8 | 11x |
| 创建 venv | 2.1 | 1.5 | 0.1 | 21x |
测试环境:macOS,Python 3.12,M2 Pro,SSD
10. 高级技巧
临时环境运行
# 无需安装,临时运行依赖
uv run --with pandas,numpy python analysis.py
# 临时运行特定版本
uv run --python 3.10 --with pytest python -m pytest
# 脚本头部声明依赖(PEP 723)
# /// script
# dependencies = ["requests>=2.25.0", "rich>=13.0.0"]
# ///
Debug 技巧
# 查看依赖树
uv pip tree
# 查看依赖解析过程(debug)
uv pip install fastapi -v
# 检查 lock 文件是否过期
uv lock --check
# 清理缓存
uv cache clean
延伸阅读
- Python Web 框架 — FastAPI/Flask/Django 项目结构
- Python 类型系统 — mypy + Pydantic 类型安全
- Python 测试策略 — pytest 与 CI 集成
- GitHub Actions CI/CD — 持续集成配置
总结
Python 工具链在 2024-2025 年经历了质的飞跃。uv 以 Rust 编写的性能优势,实现了包管理、虚拟环境和 Python 版本管理的统一;ruff 将 lint、format、import 排序等功能集成到单一工具中,速度是传统工具的数十倍。对于 Python 开发者而言,现在是从传统工具链(pip + virtualenv + black + flake8 + isort)向现代化工具链(uv + ruff + mypy)迁移的最佳时机。迁移过程可以渐进式进行:先用 uv 替代 pip,再引入 ruff 替换 lint/format 工具,最后将 CI/CD 流水线升级到新工具链。这套现代化工具不仅提升了开发效率,更重要的是通过一致的配置和自动化的代码检查,确保团队代码质量的稳定和可维护性。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。