Ruff — 超快 Python Linter & Formatter¶
一句话说明: Ruff 是用 Rust 编写的 Python 代码检查和格式化工具,速度比 Flake8 快 10-100 倍,且整合了数十个工具的规则。
为什么要学¶
- 面试加分 — 展示你重视代码质量自动化,理解 linting 在 CI/CD 中的角色
- 实用性 — 一个工具替代 Flake8 + isort + pyupgrade + autoflake + pydocstyle + ...
- 速度 — 大项目(万级文件)也能亚秒完成检查
- 零配置 — 开箱即用合理默认,渐进式启用更多规则
核心概念详解¶
Linter vs Formatter¶
白话: - Linter(检查器):找出代码中的 bug、风格问题、反模式(类似老师改作业划红线) - Formatter(格式化器):自动把代码排版整齐(类似 Word 的自动排版)
| 对比项 | Flake8 + isort + Black | Ruff |
|---|---|---|
| 工具数 | 3-8 个 | 1 个 |
| 配置文件 | 多个 | 1 个 |
| 速度 | 秒-分钟 | 毫秒 |
| 自动修复 | 部分支持 | 广泛支持 |
| 维护成本 | 各工具版本对齐 | 统一更新 |
规则体系¶
白话: Ruff 把 Flake8 及其几十个插件的规则都内置了,用前缀字母区分来源。
| 前缀 | 来源 | 用途 |
|---|---|---|
E/W | pycodestyle | 基础风格 |
F | Pyflakes | 逻辑错误 |
I | isort | import 排序 |
UP | pyupgrade | 升级旧语法 |
B | flake8-bugbear | 常见 bug |
S | flake8-bandit | 安全问题 |
N | pep8-naming | 命名规范 |
D | pydocstyle | 文档规范 |
Fix vs Check¶
白话: ruff check 只报告问题,ruff check --fix 自动修复能安全修复的问题(unsafe fix 需要额外确认)。
安装与配置¶
# 推荐:用 uv 安装
uv tool install ruff
# 或 pip
pip install ruff
# 或 Homebrew
brew install ruff
# 验证
ruff --version
配置文件 pyproject.toml¶
[tool.ruff]
# 目标 Python 版本
target-version = "py312"
# 行长度限制
line-length = 88
# 排除目录
exclude = [
".venv",
"migrations",
"__pycache__",
]
[tool.ruff.lint]
# 启用的规则集
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"UP", # pyupgrade
"S", # bandit (安全)
"N", # pep8-naming
]
# 忽略的特定规则
ignore = [
"E501", # 行长度(交给 formatter)
]
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["S101"] # 测试文件允许 assert
[tool.ruff.format]
# 引号风格
quote-style = "double"
# 缩进风格
indent-style = "space"
快速上手¶
5 分钟入门¶
# 检查代码(当前目录)
ruff check .
# 自动修复
ruff check --fix .
# 格式化代码(替代 Black)
ruff format .
# 检查格式是否规范(CI 用)
ruff format --check .
# 查看某条规则的说明
ruff rule E711
输出示例¶
src/main.py:3:1: F401 [*] `os` imported but unused
src/main.py:10:5: UP006 [*] Use `list` instead of `List` for type annotation
src/utils.py:25:9: B006 Do not use mutable data structures for argument defaults
Found 3 errors.
[*] 2 fixable with `--fix`
进阶用法¶
1. 渐进式采用策略¶
# 阶段1:只启用基础规则(零噪音)
[tool.ruff.lint]
select = ["E", "F"]
# 阶段2:加入 import 排序和升级建议
select = ["E", "F", "I", "UP"]
# 阶段3:完整规则集
select = ["E", "W", "F", "I", "B", "UP", "S", "N", "D", "ANN"]
2. 与编辑器集成¶
VS Code:
// .vscode/settings.json
{
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
}
}
3. Pre-commit Hook¶
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff # linter
args: [--fix]
- id: ruff-format # formatter
4. GitHub Actions¶
name: Lint
on: [push, pull_request]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v1
with:
args: "check --output-format=github"
- uses: astral-sh/ruff-action@v1
with:
args: "format --check"
5. 自定义规则组合(按项目类型)¶
# Web API 项目
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "S", "ASYNC"]
# 数据科学项目
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "NPY", "PD"] # NumPy + Pandas 规则
# 库/框架项目
[tool.ruff.lint]
select = ["ALL"]
ignore = ["D100", "D104"] # 启用全部但忽略噪音
6. Notebook 支持¶
# 检查 Jupyter Notebook
ruff check --extend-include "*.ipynb" .
# 格式化 Notebook
ruff format --extend-include "*.ipynb" .
常见问题与排错¶
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 与 Black 格式冲突 | 两者规则不完全一致 | 完全迁移到 ruff format,移除 Black |
| 太多报错 | 启用了过多规则 | 渐进启用,先 select = ["E", "F"] |
| 误报 | 规则不适用于某段代码 | 行内 # noqa: RULE 或 per-file-ignores |
| isort 与 ruff 冲突 | 两者都在排 import | 移除 isort,用 Ruff 的 I 规则 |
| 旧项目迁移 | 存量代码太多错误 | 用 --fix 批量修复 + --add-noqa 标记剩余 |
面试高频考点¶
- 为什么 Ruff 比 Flake8 快?
Rust 实现、并行文件处理、无 Python 解释器开销
Linter 和 Formatter 的职责边界?
Linter 检查逻辑/风格问题、Formatter 统一排版格式,Ruff 两者兼具
如何在大型项目中引入 Linter?
渐进式:少规则→多规则,先 fix→后强制,配合 CI gate
--fix为什么分 safe 和 unsafe?safe fix 不改变语义(如删未用 import);unsafe 可能改变行为(需人工确认)
Pre-commit hook 的意义?
- 提交前自动检查,保证代码库始终符合规范,减少 PR 噪音