Ruff:一个工具终结你的Python代码洁癖
2026/6/13 10:02:36 网站建设 项目流程

一、Python开发者的"工具地狱"

如果你维护过一个中大型Python项目,大概率经历过这样的场景:flake8 做静态检查,black 管格式化,isort 理导入顺序,pydocstyle 查文档字符串,pyupgrade 做语法现代化升级,autoflake 清未使用的导入……一个 pre-commit 钩子里塞了五六种工具,CI 流水线跑一次代码检查要等几十秒甚至几分钟,本地改一行代码按下保存后,等着各种工具排队运行。

这还不算版本兼容问题。flake8 和 black 偶尔对同一行代码有不同看法,配置项散落在 setup.cfg、pyproject.toml、.flake8 三个文件里,改一条规则要在好几个地方同步。新成员入职,光配开发环境就要折腾半小时。

有没有一个工具能把这些全干掉,还比它们加起来快100倍?

这就是 Ruff。

二、Ruff 是什么

Ruff 是 Astral 公司用 Rust 写的高性能 Python linter 和 formatter,开源(MIT 协议),2022 年发布至今 GitHub star 数已超 35k。它要解决的核心问题很直白:你不再需要 flake8、black、isort、pydocstyle、pyupgrade、autoflake 中的任何一个,一个 ruff 命令全部搞定,而且快到让你怀疑它到底有没有在干活。

FastAPI 创始人 Sebastián Ramírez 的原话是:"Ruff is so fast that sometimes I intentionally introduce an error just to make sure it's still running."

三、核心优势拆解

3.1 性能:碾压级的快

Ruff 到底有多快?看一组实测对比(项目:Django 源码,约 60 万行 Python):

工具单次扫描耗时相对 Ruff 的倍数
Ruff0.12 秒1x
Flake814.3 秒~120x
Pylint42.8 秒~357x
Black(格式化)2.1 秒~18x
Ruff formatter0.18 秒1x

Dagster 创始人 Nick Schrock 分享过:在他们 25 万行的代码库上,Pylint 需要 2.5 分钟,Ruff 只用0.4 秒

快的秘密有两个层面:

  • 语言层面:Rust 零成本抽象 + 无 GC + 编译到原生代码,直接避免了 Python 解释器开销。Flake8 底层其实是 Python 进程,每个检查插件都在 Python 虚拟机里跑一遍 AST,而 Ruff 在 Rust 里一次性构建 AST 后批量执行所有规则。
  • 架构层面:增量缓存 + 多线程并行。改了一个文件只检查那一个,没改的直接读缓存跳过。配合 --watch 模式,每次保存瞬间出结果。

3.2 规则库:800+ 条开箱即用

Ruff 重新实现了几乎所有主流 Flake8 插件的规则,按字母前缀分类:

前缀来源/类别规则数举例
E/Wpycodestyle71E501(行太长)
FPyflakes58F841(未使用变量)
Bflake8-bugbear68B006(可变默认参数)
Iisort20I001(导入顺序)
SIMflake8-simplify30SIM108(用三元表达式)
UPpyupgrade46UP006(用 list 替代 typing.List)
Npep8-naming32N801(类名应大写开头)
Dpydocstyle70D100(模块缺文档字符串)

你可以按需启用:想要严格的类型注解检查?加 ANN。想做安全审计?加 S(bandit)。想强制写 docstring?加 D。一条 select 配置搞定,不用装七个插件。

3.3 自动修复能力

Ruff 不是"只告诉你哪里错了"的唠叨工具。大量规则支持 --fix 自动修复,而且分两个安全等级:

  • 安全修复(safe fix):绝对不会改变代码语义。比如删掉未使用的导入 import os、把 list() 改成 []、修复缩进对齐。
  • 不安全修复(unsafe fix):可能会改变行为,需要你确认。比如删除未使用的变量 x = expensive_call()——删了变量,函数调用也不执行了。

运行 ruff check --fix 只应用安全修复;加上 --unsafe-fixes 才上第二档。这个设计很聪明:你可以在 CI 里只跑安全修复,在本地手动确认后再跑不安全修复。

3.4 统一格式化器

v0.1.0 起 Ruff 内置了自己的格式化器,目标是 99.9% 兼容 Black 的输出风格,同时快 10-30 倍。关键特性:

  • 与 linter 共享配置:不会出现"linter 说要这样、formatter 偏要那样"的冲突。因为两个功能跑在同一套 AST 上。
  • 2026 Style Guide:v0.15.0 引入了更激进的格式化风格(如 lambda 体自动加括号、Python 3.14+ 的 except 元组去括号),向前兼容未来 Python 语法。
  • 行宽、引号风格、缩进等全部可配置,行为与 Black 一致但更多控制权。

3.5 编辑器集成体验

VS Code 官方扩展 charliermarsh.ruff 在保存时自动运行 Ruff,错误红色波浪线 + 一键修复。JetBrains 系(PyCharm)、Neovim、Emacs 也都有成熟集成。

最直观的感受:保存文件后 100ms 内,IDE 里所有格式问题和 lint 警告全部更新。不再像以前用 flake8 那样,改完一行等两秒才看到红线冒出。

四、适用场景

场景一:新项目一杆到底

从项目第一天就把 Ruff 引入,配置好 pyproject.toml,pre-commit 一挂,团队成员零成本上手。

场景二:老项目迁移"剃头"

接手一个几万行的老代码库,代码风格参差不齐。用 Ruff 的 --fix 一次性批量修复,再配置 CI 阻止新增问题。迁移成本极低:在 pyproject.toml 里加一段配置,CI 脚本里加一行 ruff check。

场景三:Monorepo 分层管理

Ruff 支持分层配置。根目录一个宽松的 ruff.toml,子包(如 src/api/ruff.toml、src/cli/ruff.toml)可以覆盖或收紧规则。每个团队管自己的风格,互不打架。

场景四:CI/CD 快速门禁

把你的 CI lint 步骤从 30 秒缩减到 0.5 秒。对频繁提交的分支来说,这个差距会滚雪球式放大。配上一个 --exit-zero,甚至可以在 PR 评论里"建议式"提示而非硬性阻断。

场景五:pre-commit 钩子零感知

# .pre-commit-config.yaml repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.15.0 hooks: - id: ruff args: [--fix] - id: ruff-format

git commit 时自动运行,快到你感觉不到它的存在——不再有"提交代码先去倒杯水"的体验。

五、从零上手:10 分钟配置指南

5.1 安装

Ruff 是单个二进制,安装方式非常多:

# 推荐:通过 uv 安装(uv 也是 Astral 出品,Python 包管理器) uv tool install ruff@latest # 传统方式 pip install ruff # 给项目加开发依赖 uv add --dev ruff # macOS/Linux 直接装二进制 brew install ruff # Windows powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"

验证:

ruff --version # ruff 0.15.0

5.2 最小化配置

在项目根目录创建 ruff.toml(也可以写在 pyproject.toml 的 [tool.ruff] 下):

# ruff.toml # 目标 Python 版本 target-version = "py312" # 行宽(与 Black 一致) line-length = 100 # ──── Linter 配置 ──── [lint] # 启用哪些规则组 select = [ "E", # pycodestyle 错误 "W", # pycodestyle 警告 "F", # Pyflakes "B", # flake8-bugbear "I", # isort(导入排序) "N", # pep8-naming(命名规范) "UP", # pyupgrade(语法现代化) "SIM", # flake8-simplify(简化建议) "C4", # flake8-comprehensions ] # 忽略特定规则(按项目需要调整) ignore = [ "E501", # 行太长(交给 formatter 处理) ] # ──── Formatter 配置 ──── [format] quote-style = "double" indent-style = "space" docstring-code-format = true

5.3 常用命令速查

# Lint 检查 ruff check # 检查当前目录 ruff check --fix # 自动修复 ruff check --fix --unsafe-fixes # 含不安全修复 ruff check --watch # 监听模式,文件变动自动检查 ruff check --statistics # 按规则统计问题数量 # 格式化 ruff format # 格式化当前目录 ruff format --check # 仅检查,不修改(CI 用) ruff format --diff # 显示差异不应用 # 查看某条规则的说明 ruff rule E501 # 查看 E501 详情 # 仅检查指定文件/目录 ruff check src/models/user.py ruff check src/

5.4 实战工作流

日常开发:配好 VS Code 扩展 + ruff.toml,保存即检查。

提交前:运行 ruff check --fix && ruff format,自动化清理。

CI 流水线(GitHub Actions 示例)

name: Lint on: [push, pull_request] jobs: ruff: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/ruff-action@v3 with: args: "check" - uses: astral-sh/ruff-action@v3 with: args: "format --check"

5.5 渐进式迁移:从 Flake8+Black 迁到 Ruff

如果你已有项目在用 Flake8 + Black + isort,迁移分三步走:

第一步:对齐规则

# 先生成当前 flake8 正在使用的规则列表 flake8 --select=E,W,F,B --format=json . > old_issues.json # 用 ruff check --statistics 对比差异 ruff check --statistics

把差异规则按需加入 ignore 或 select。

第二步:一次性批量修复

ruff check --fix --unsafe-fixes # 先修 lint ruff format # 再格式化

建议在一个独立分支上执行,方便 code review 对比 diff。

第三步:替换 CI 和 pre-commit

删掉 .flake8、pyproject.toml 里的 isort 配置,把 CI 脚本里的 flake8 + black --check + isort --check 换成两行 ruff check + ruff format --check。

迁移完成后的收益非常直观:以 Django 规模的项目为例,CI lint 步骤从~22 秒降至 ~0.3 秒

六、Ruff vs 同类方案

维度RuffFlake8 + 插件Black + isort + Pylint
安装复杂度单二进制5-10 个 pip 包3 个 pip 包
配置文件1个 tomlsetup.cfg + .flake8 + tox.inipyproject.toml + .pylintrc
Lint 速度(Django 规模)0.12s14s42s
Formatter 速度0.18s不适用2.1s(仅 Black)
内置规则数800+100+(基础)400+
自动修复安全/不安全双档有限有限
规则冲突处理无(同 AST)常有常有
编辑器体验保存即检查有延迟明显延迟
社区生态快速增长成熟但停滞成熟

七、实践建议与注意事项

建议

  1. 新项目直接上 Ruff——没有历史包袱,一开始就严格配置 select,养成好习惯。

  2. 老项目用 --fix 一次性剃头,然后在 CI 中只跑 ruff check(不加 --fix),阻断新增问题。

  3. 善用 per-file-ignores。比如测试文件里放宽某些规则:

    [lint.per-file-ignores] "tests/**/*.py" = ["D100", "S101"] # 测试不需要模块文档字符串,允许 assert
  4. 配合 uv 做全链路 Rust 化:uv 管理依赖 + Ruff 管理代码质量,两个工具都来自 Astral,协作零摩擦。

注意事项

  • Ruff 的规则实现是"重新实现"而非"调用原版",极少数边界情况可能与 Flake8 行为有微小差异。迁移后建议跑一轮完整对比。
  • Formatter 稳定版已发布(v0.1.0 起),但不保证与 Black 的每一个空格位置完全一致。对格式极其敏感的场景,先用 ruff format --diff 预览。
  • 部分冷门 Flake8 插件尚未被 Ruff 重写。如果你的项目严重依赖某个小众插件,先检查 Ruff 是否已覆盖对应规则前缀。

Ruff 用了三年时间(2022-2025)从"又一个 linter"成长为 Python 代码质量的事实标准工具链。它证明了"用 Rust 重写 Python 工具"不是噱头,而是从架构层面真正改变了开发者的日常体验——把原本需要排队等十几秒的检查压缩到在你松开拓键之前就已完成。如果你还没试过,给你的主项目跑一次 pip install ruff && ruff check --statistics,看看它会检出什么,大概率你会立刻把 .flake8 删掉。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询