跳转至

Ruff — 超快 Python Linter & Formatter

一句话说明: Ruff 是用 Rust 编写的 Python 代码检查和格式化工具,速度比 Flake8 快 10-100 倍,且整合了数十个工具的规则。


为什么要学

  1. 面试加分 — 展示你重视代码质量自动化,理解 linting 在 CI/CD 中的角色
  2. 实用性 — 一个工具替代 Flake8 + isort + pyupgrade + autoflake + pydocstyle + ...
  3. 速度 — 大项目(万级文件)也能亚秒完成检查
  4. 零配置 — 开箱即用合理默认,渐进式启用更多规则

核心概念详解

Linter vs Formatter

白话: - Linter(检查器):找出代码中的 bug、风格问题、反模式(类似老师改作业划红线) - Formatter(格式化器):自动把代码排版整齐(类似 Word 的自动排版)

对比项Flake8 + isort + BlackRuff
工具数3-8 个1 个
配置文件多个1 个
速度秒-分钟毫秒
自动修复部分支持广泛支持
维护成本各工具版本对齐统一更新

规则体系

白话: Ruff 把 Flake8 及其几十个插件的规则都内置了,用前缀字母区分来源。

前缀来源用途
E/Wpycodestyle基础风格
FPyflakes逻辑错误
Iisortimport 排序
UPpyupgrade升级旧语法
Bflake8-bugbear常见 bug
Sflake8-bandit安全问题
Npep8-naming命名规范
Dpydocstyle文档规范

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 标记剩余

面试高频考点

  1. 为什么 Ruff 比 Flake8 快?
  2. Rust 实现、并行文件处理、无 Python 解释器开销

  3. Linter 和 Formatter 的职责边界?

  4. Linter 检查逻辑/风格问题、Formatter 统一排版格式,Ruff 两者兼具

  5. 如何在大型项目中引入 Linter?

  6. 渐进式:少规则→多规则,先 fix→后强制,配合 CI gate

  7. --fix 为什么分 safe 和 unsafe?

  8. safe fix 不改变语义(如删未用 import);unsafe 可能改变行为(需人工确认)

  9. Pre-commit hook 的意义?

  10. 提交前自动检查,保证代码库始终符合规范,减少 PR 噪音

参考资源