如果你还在用Flake8做代码检查、用Black做格式化、用isort排导入、用pydocstyle检查文档字符串——那你应该已经感觉到了,每次pre-commit跑完那几十秒、甚至几分钟的等待,积少成多,真的很消磨耐心。
Ruff就是冲着这个问题来的。
它是Astral团队(就是搞uv和ty的那帮人)用Rust写的Python linter和formatter。GitHub上star数早就过了十万,CPython代码库从头到尾lint一遍都没问题。FastAPI的作者Sebastián Ramírez有句评价特别到位:“Ruff快到我有时候会故意在代码里加个bug,就为了确认它真的在跑、真的在检查。”
今天就从头开始,把Ruff装起来、用起来、配置起来,看看它到底能帮你省多少时间。
安装:pip install就够了
Ruff的安装方式和普通Python包一样简单:
它和Flake8、Black这些工具最大的区别在于——安装的不是一堆Python脚本,而是一个编译好的Rust二进制文件。所以装完之后直接就能用,不需要额外装一堆插件。
装完验证一下:
基本用法:一行命令搞定检查和格式化
Ruff同时包含了linter和formatter两个功能。用法非常直接。
代码检查:
这条命令会检查当前目录下所有Python文件,输出所有发现的问题。
自动修复:
很多问题Ruff能自动修——比如删除未使用的导入、修复格式问题。加个--fix参数,能修的都帮你修了。
代码格式化:
格式化风格和Black基本一致。如果你之前用Black,切到Ruff的formatter几乎不需要改任何习惯。
单个文件也支持:
ruff check path/to/file.pyruff format path/to/file.py
配置文件:pyproject.toml一站搞定
Ruff支持通过pyproject.toml、ruff.toml或.ruff.toml配置。推荐直接用pyproject.toml,和项目其他配置放一起。
一个最基础的配置大概长这样:
[tool.ruff]line-length = 88target-version = "py310"[tool.ruff.lint]select = ["E4", "E7", "E9", "F"]ignore = []fixable = ["ALL"][tool.ruff.format]quote-style = "double"indent-style = "space"
select指定了要开启的规则——默认只开了Flake8的一部分(E4/E7/E9和Pyflakes的F)。如果你想把规则开全一点,可以改成:但第一次用建议别直接开ALL,几百条规则同时生效,输出会非常壮观。先从默认配置开始,慢慢加。
规则覆盖:900+条,把主流插件全包了
Ruff内置了超过900条规则,覆盖了Flake8、pycodestyle、pydocstyle、pyupgrade、isort、pep8-naming这些工具的功能。换句话说,原来你装一堆插件才能实现的功能,Ruff一个工具全包了。
具体支持哪些插件?README里列了长长一串:
flake8-annotations、flake8-bandit、flake8-bugbear、flake8-builtins、flake8-comprehensions、flake8-datetimez、flake8-debugger、flake8-errmsg、flake8-implicit-str-concat、flake8-import-conventions、flake8-logging、flake8-no-pep420、flake8-pie、flake8-print、flake8-raise、flake8-return、flake8-self、flake8-slots、flake8-super、flake8-tidy-imports、flake8-todos、flake8-type-checking、flake8-use-pathlib、flynt、isort、mccabe、pandas-vet、pep8-naming、pydocstyle、pygrep-hooks、pylint-airflow、pyupgrade、tryceratops、yesqa
如果你想查看所有支持的规则,官方文档有完整列表。
和现有工具共存:Ruff能不能直接替换Flake8+Black+isort?
能。而且官方就是这么设计的。
Ruff的linter对标Flake8(及其几十个插件),formatter对标Black,import排序对标isort,文档字符串检查对标pydocstyle,语法升级对标pyupgrade,自动删除未导入对标autoflake。一个工具替掉这一堆,配置文件也从分散的.flake8、pyproject.toml(Black)、.isort.cfg收敛到一份pyproject.toml里。
替换的过程可以分步走。先只开Ruff的check,不开format,看看输出是不是符合预期。确认没问题之后,把ruff format加进CI流程,逐渐把Black替换掉。Ruff的formatter和Black在输出上高度一致,替换过去基本不会有格式上的意外。
pre-commit集成:把Ruff加进提交钩子
如果你在用pre-commit,Ruff官方提供了专用hook:
- repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.15.18 hooks: - id: ruff-check args: [--fix] - id: ruff-format
这样每次commit的时候,Ruff会自动检查并修复代码,格式化也会一并完成。
VS Code插件:保存即检查
Ruff有官方VS Code扩展。装完之后配置一下:
{ "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true }, "ruff.lint.run": "onSave"}
保存文件的时候自动格式化和检查,体验非常流畅。
性能到底有多快?
官方给的数据是比Flake8快10到100倍。
我自己在一个中型Django项目(大约200个Python文件)上试过:Flake8跑完大概需要4.5秒,Ruff check只用了0.3秒。格式化方面,Black跑完全部文件用了2.8秒,Ruff format用了0.2秒。十几个人的团队,每人每天commit几十次,省下来的时间累积起来相当可观。
速度快的核心原因有两个:Rust编译成原生二进制,没有Python解释器的启动开销;内置缓存机制,没改过的文件直接跳过。
一些提醒
Ruff目前还不支持所有Flake8插件的全部功能,但主流的那几十个都已经覆盖了。如果你用了某个特别冷门的插件,建议先去官方文档查一下支持情况。
另外,Ruff不做类型检查——那是mypy或pyright的活儿。Ruff的定位是linting + formatting + import sorting,类型检查不在它的范围内。
一点实在的看法
Ruff这个项目最打动我的地方,不是它快,而是它“快得有道理”。它不是靠偷工减料换来的速度,而是用Rust重写了整个工具链,从架构上解决了Python工具慢的根本问题。而且Astral团队一直在迭代,生态也越来越成熟。如果你还在用Flake8 + Black + isort那套组合,花半天时间把Ruff迁过去——省下来的时间,几天就回本了。
项目地址:https://github.com/astral-sh/ruff
官方文档:https://docs.astral.sh/ruff/