Python 现代工具链:uv + ruff + mypy 全链路工程实践

Python 工具链现代化完整指南:uv(极速包管理+虚拟环境+Python 安装)、ruff(lint+format 一体化)、mypy/pyright 类型检查、pipx 工具安装、 hatch/poetry/pdm 项目管理、从 pip 到 uv 的迁移路径。附带 pyproject.toml 完整配置模板。

2024-2025 年 Python 工具链经历了革命性更新:uv 以 Rust 编写,替代 pip + virtualenv + poetry 的组合;ruff 统一了 flake8 + black + isort 的功能。本文提供「一步到位」的现代化迁移方案。


1. uv:一站式 Python 包管理器

1.1 为什么选 uv

工具安装速度虚拟环境Python 版本依赖锁定
pip慢(逐包下载)需 virtualenvrequirements.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代码格式化内置(无前缀)
isortimport 排序I
flake8代码风格检查E, W, F
pyupgradePython 升级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

延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「python」更多文章