Loading...

文章背景图

Ruff 极速 Python 代码检查与格式化工具本地部署指南

2026-10-27
0
- 字
- 分钟
|

Ruff 极速 Python 代码检查与格式化工具本地部署指南

Ruff 性能基准

一、项目介绍

Ruff 是一个用 Rust 编写的极速 Python 代码检查器(linter)与格式化工具。它的目标是在一个接口下替代 Flake8(及其数十个插件)、Black、isort、pydocstyle、pyupgrade、autoflake 等一整套 Python 工具链,同时速度比任何单个工具都快一到两个数量级。

官方称其比现有 linter 与格式化工具快 10–100 倍,内置超过 900 条规则,并以 Rust 原生重新实现了 flake8-bugbear、isort、pyupgrade 等流行插件的行为。它支持 pyproject.toml 配置、内置缓存、自动修复(如删除未使用的 import)、pre-commit 钩子、VS Code 等编辑器集成,以及 GitHub Action。

这种"一个二进制替代一堆 Python 包"的思路,正好切中了 Python 工具链长期臃肿的痛点。过去为了代码质量要装好几个包、配好几条命令,现在一个 Ruff 全包了。安装快、运行快、配置简单,体验上的飞跃让它迅速成为新项目的默认选择。

由 Astral 出品

Ruff 由 Astral 公司(同时也是 uv 与 ty 的作者)维护,已被 Apache Airflow、FastAPI、Hugging Face Transformers、Pandas、SciPy 等大型开源项目采用。对 Python AI 工程团队而言,Ruff 已成为代码质量工具链的事实标准之一。

为什么需要这么快的 linter

在大型 Python 代码库中,传统工具链(Flake8 + 多个插件 + isort + Black)加起来往往要跑几十秒甚至几分钟。这意味着你不会在每次保存时都检查代码,只能在提交前或 CI 里跑一次——问题被推迟发现,修复成本变高。Ruff 用 Rust 把整套工具链压缩成一个二进制,扫描几十万行代码常常不到一秒。这种速度让"保存即检查"成为可能,也让它能塞进编辑器的实时反馈与 pre-commit 钩子,在你敲代码的瞬间就指出未使用的 import、未定义的变量、不符合风格的引号。

对 AI 项目尤其如此:数据处理脚本、训练配置、模型推理代码往往散落多处,Ruff 可以在不拖慢迭代的前提下守住基本质量线。它不替代类型检查(那是 mypy/pyright 的事),也不替代测试,但它能在很早的阶段抓住大量低级错误。

从工程角度看,Ruff 真正革命性的不是某一条规则,而是"把检查延迟降到接近零"这件事本身。当一次扫描只要几十毫秒,你就愿意在编辑器里开实时检查;当 pre-commit 钩子几乎不耗时,你就愿意对每个改动都跑一遍。工具链的摩擦一旦变小,好习惯就不再需要意志力来维持。这也是为什么它能在短短几年内从一个新兴工具变成众多大型项目的默认选择——它降低的不是代码质量标准,而是遵守标准的成本。

另一个值得注意的点是它对 Python 版本演进的跟进速度。Ruff 由 Rust 写成,发布节奏快,新语法、新规则往往在官方 PEP 落地后很快支持,甚至能检查到尚未发布的 Python 版本语法。对长期项目来说,这意味着升级 Python 版本时不必担心工具链跟不上。

二、官方信息

项目 信息
仓库地址 astral-sh/ruff
官方文档 docs.astral.sh/ruff
在线 playground play.ruff.rs
PyPI 包 ruff
开源协议 MIT
实现语言 Rust
最近更新 2026-10-27

Ruff 图标

三、项目结构与核心特性

Ruff 是一个单二进制命令行工具,不需要在你的项目里安装一堆 Python 插件。核心能力:

  • 极速:用 Rust 编写,扫描整个代码库通常在亚秒级完成。
  • Lint + Format 一体:ruff check 做静态检查,ruff format 做格式化,可互相配合。
  • 兼容现有工具:与 Flake8、isort、Black 的配置与行为高度对齐,可平滑迁移。
  • 900+ 规则:覆盖错误检查、风格、import 排序、文档字符串、pyupgrade 等。
  • 自动修复:--fix 可自动修正大量问题(未使用 import、废弃调用等)。
  • 内置缓存:跳过未修改文件,二次扫描更快。
  • 分层配置:支持 monorepo,按目录级联配置。
  • 编辑器与 CI 集成:VS Code 扩展、pre-commit、GitHub Action 一应俱全。

这些特性合起来,让 Ruff 不只是一个命令行工具,而是一套能嵌进开发全流程的质量防线:写代码时编辑器实时提示、提交时 pre-commit 拦截、合并前 CI 兜底。三道关卡都用同一个二进制,规则一致、速度一致,不会出现"本地能过、CI 报错"的割裂。

四、环境与版本要求

组件 版本要求 说明
Python 3.7+(被检查的代码) Ruff 兼容检查到 Python 3.15
操作系统 Linux / macOS / Windows 提供预编译二进制
安装方式 pip / uv / pipx / Homebrew / conda 任选其一

Ruff 本身是 Rust 编译的二进制,运行不依赖 Python 解释器;它处理的是你的 Python 源码文件。

这一点带来一个意外好处:即使你的项目锁定在较老的 Python 版本,也不影响使用最新的 Ruff 来检查代码。因为 Ruff 是独立二进制,不会被项目的 Python 版本绑死,团队可以统一升级 Ruff 版本而不必同步升级解释器。这在维护多年老项目时尤其方便。

五、本地部署步骤

1. 安装 Ruff

用 pip:

pip install ruff

用 uv(Astral 自家工具,推荐):

uv tool install ruff@latest
# 或作为项目开发依赖
uv add --dev ruff

用 pipx:

pipx install ruff

macOS/Linux 也可以用独立安装脚本:

curl -LsSf https://astral.sh/ruff/install.sh | sh

Windows PowerShell:

powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"

此外还支持 Homebrew(brew install ruff)、Conda(conda install -c conda-forge ruff)。

2. 验证安装

ruff --version
ruff check --help

能输出版本号就说明二进制在路径里。如果提示命令找不到,多半是安装时的 bin 目录没进 PATH——用 pip 装的话确认虚拟环境已激活,用独立脚本装的话按提示把 ~/.local/bin 加进 PATH。这一步看似简单,但很多人卡在"装好了却调不到命令"上。

3. 运行检查(lint)

# 检查当前目录及子目录所有 .py 文件
ruff check

# 检查指定路径
ruff check path/to/code/

# 检查单个文件
ruff check path/to/code/to/file.py

4. 自动修复问题

ruff check --fix

这会自动删除未使用的 import、修复 pyupgrade 建议等。建议在版本控制干净的状态下运行,方便 review。

5. 运行格式化

# 格式化当前目录
ruff format

# 格式化指定文件
ruff format path/to/code/to/file.py

Ruff 的 formatter 与 Black 风格对齐(双引号、4 空格缩进、尊重魔法尾逗号)。

6. 配置文件

在项目根目录创建 pyproject.toml:

[tool.ruff]
line-length = 88
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "W", "I", "UP", "B"]
ignore = []

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

也可以用独立的 ruff.toml 或 .ruff.toml。默认配置等价于:行宽 88、缩进 4 空格、目标 Python 3.11、启用 F/E/B/UP/RUF 等规则。

7. 集成 pre-commit

在 .pre-commit-config.yaml 中:

repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.17.3
    hooks:
      - id: ruff-check
        args: [--fix]
      - id: ruff-format

第一次启用建议先用 ruff check 看看报哪些问题,不要一上来就自动修复全量代码。先了解规则、再选择性修复,能避免一次改动过大难以评审。

六、API 用法与示例

Ruff 是命令行工具,不提供 Python 库 API(它是给工具链用的,不是给业务代码 import 的)。下面是常用命令组合。

1. 选择规则

# 只检查未使用 import(F401)与未定义名字(F821)
ruff check --select F401 --select F821

# 安静模式
ruff check --quiet

按规则代码选择检查项,是迁移期最常用的技巧。刚引入 Ruff 的项目往往会被上百条历史警告淹没,这时先用 --select 只开几条最重要的规则(比如 F 开头的 pyflakes 类错误),跑通 CI 后再逐步加规则,比一次性全开更容易落地。等团队习惯了,再把规则集写进配置文件,固定下来。

2. 内联配置

# 通过 --config 传单行配置
ruff check --config "lint.per-file-ignores = {'some_file.py' = ['F841']}"

3. 预览模式

启用尚未稳定的新规则与风格变更:

ruff check --preview
ruff format --preview

或在配置里设置 preview = true。

4. GitHub Action

name: Ruff
on: [push, pull_request]
jobs:
  ruff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/ruff-action@v3

5. 查看某条规则详情

ruff rule F401
ruff rule E501

会打印规则说明、为什么启用、修复示例。

团队落地 Ruff 的建议

如果团队之前用 Flake8 + Black + isort,迁移时不要一步到位。建议第一阶段只把 ruff check 作为信息性输出(不阻断 CI),看它报出多少历史问题;第二阶段用 --fix 批量自动修复能修的部分,把剩余问题列入技术债;第三阶段再把它设为阻断性检查,并在 pre-commit 里启用。这样不会因为一次迁移产生上千行 diff 而让 code review 瘫痪。

配置上,建议在 pyproject.toml 里固定 target-version(和项目实际支持的 Python 版本一致),并显式 select 需要的规则集,而不是长期用默认值——等团队熟悉后,再逐步加入 B(flake8-bugbear)、UP(pyupgrade)、I(isort)等类别。对 AI 项目来说,脚本里常有动态 import、字符串拼接、实验性代码,可以用 per-file-ignores 对数据探索脚本放宽规则,对生产代码保持严格。

Ruff 与同类工具的关系

理解 Ruff 的定位,要先理清 Python 工具链的分工。mypy/pyright 做静态类型检查,关注"这个变量是不是字符串"这类语义问题;pytest 跑运行时行为;Ruff 做的是"静态风格与常见错误"——未使用的 import、未定义的变量、不符合 PEP 8 的缩进、错误的异常捕获写法。它不替你判断类型对不对,也不跑你的代码,而是在你敲完的瞬间扫一遍源码文本。

它和 Black、isort 的关系是"兼容并替代":Black 只管格式化(长什么样),isort 只管 import 顺序,Ruff 把这两件事和上百条错误检查合到一个二进制里。对你的项目来说,意味着少装几个包、少配几条 CI、少等几秒。如果团队已经深度依赖某个 Flake8 插件的特殊规则,迁移前先查 Ruff 规则列表看是否已覆盖;未覆盖的部分可以暂时保留原工具,逐步过渡。

配置与编辑器集成的实战

Ruff 的配置可以放在 pyproject.toml、ruff.toml 或 .ruff.toml。对已有 Black 配置的项目,最省事的是在 pyproject.toml 里设 [tool.ruff] 并把 line-length 对齐现有值,再用 ruff format 代替 Black——它默认就和 Black 风格一致,连 skip-string-normalization 这类选项都有对应。per-file-ignores 是最有用的功能之一:数据探索 notebook、脚本目录、迁移脚本往往不需要严格规则,可以按路径单独放宽。

编辑器侧,VS Code 装 Ruff 扩展后,把它设为默认 formatter 与 linter,保存即检查、保存即格式化。配合"保存时修复"(source.fixAll.ruff),未使用的 import 会在保存时自动删掉,体验接近现代语言工具链。这种即时反馈能在写代码的当下就拦住低级错误,而不是等到 CI 报红。对 AI 团队来说,把 Ruff 加进仓库模板,新成员 clone 下来跑 ruff check 就能立刻得到一致的代码风格,减少 review 里的格式争论。

配置好后基本无需再管,它会在提交前自动把问题挡下来。

团队统一开启后,代码风格争议会少很多。

用起来后就会离不开它。

它是 Python 工具链现代化的代表之作。

七、常见问题 FAQ

下面整理了初次安装与配置 Ruff 时最常遇到的几个疑问,供快速排查参考。规则太严、自动修复改太多、与既有工具冲突是常见困扰,下面说明如何按需收敛。

Q1:Ruff 能完全替代 Flake8 + Black + isort 吗?
对绝大多数项目可以。Ruff 与这三者在规则与格式上高度对齐,但个别插件的边缘行为可能有差异。建议先用 ruff check 与现有工具并行跑一段时间,再彻底切换。

Q2:迁移到 Ruff 后,原来的 # noqa 注释还能用吗?
能用。Ruff 兼容 # noqa: F401 这类注释语法,迁移成本很低。

Q3:Ruff 支持 type checking 吗?
不支持。Ruff 做的是 lint 与格式化,类型检查请配合 mypy、pyright 等工具。

Q4:为什么我安装后 ruff 命令找不到?
如果用 pipx/uv 安装,确保其 bin 目录在 PATH 中。用 pip 安装时确认虚拟环境已激活。独立安装脚本会提示你把 ~/.local/bin 加入 PATH。

Q5:如何固定团队使用的 Ruff 版本?
在 pre-commit 配置中写死 rev: v0.17.3,或在 requirements-dev.txt/pyproject.toml 中锁定版本。Ruff 更新较快,团队统一版本可避免 CI 与本地结果不一致。

总的来说,Ruff 的价值在于把"遵守代码规范"的成本降到几乎为零。装好、配好、接进编辑器和 pre-commit 之后,它就在后台安静地工作,你几乎感觉不到它的存在,但代码质量的底线却被稳稳守住。对快速迭代的 AI 团队来说,这种"无感但可靠"的工具,正是把精力留给模型与业务、而不是风格争论的关键。

以上就是 Ruff 的安装、配置与基本用法。一个 Rust 二进制替代整套 Python 工具链,速度与一致性都值得长期使用。

八、相关链接

本文命令与默认配置对照仓库 README 整理,Ruv 版本更新频繁,具体规则与配置项请以官方文档为准。

评论交流

文章目录