ruff list --select 使用指南:高效筛选与管理 Python lint 规则 你有没有遇到过这种情况项目里ruff check一直在报某个规则代码读了半天也不确定它到底归在哪一类想看看某条规则编号对应的完整说明又懒得去翻文档。后来我养成了一个习惯先跑一遍ruff list再加--select N把规则列表筛到只剩自己想看的那几条。这条命令看起来不起眼但它才是“手工调教 lint 规则”的第一步。ruff list --select N里的 N 不是某个神秘参数它代表你在查询时传入的规则选择器比如E501、F401、E4这类前缀或完整规则号。很多人把它和ruff check --select N搞混前者只是“列出并筛选规则目录”后者才是“在检查时启用哪些规则”。这篇文章我会把 list 命令背后的规则体系讲清楚再给你几组可以直接抄走的筛选组合最后聊聊我在实际项目里踩过哪些坑。1. 先搞懂 list 命令在查什么1.1 ruff 的规则不是一堆散乱的编号ruff 的规则体系看起来是“字母数字”实际上它是分层级的。拿E501来说E 是大类E5 是子类E501 才是一条具体规则。这种分层不是为了好看而是为了让使用者可以按“类别”或“子类别”灵活筛选而不是一次只能选一条规则。具体到命令行工具里规则号承担着三重身份大类 selector比如E代表 pycodestyle 的错误类F代表 Pyflakes 类W代表警告类。子类 selector比如E4代表导入相关ImportE5代表行长度、空行等风格问题。完整规则代码比如E501就是“line too long行过长”F401就是“imported but unused导入未使用”。ruff list默认输出的就是这整棵规则树。你看到的不只是一串代码每条规则还会带上名字、所属选择器、是否需要 Python 版本、是否支持自动修复等信息。列表很长所以--select N就是给这份目录做关键词过滤的工具。如果你只看过ruff check --select可能会觉得 list 完全是另一个世界。实际上两者共享同一套选择器语法。理解一套另一套基本上就通了。1.2 list 命令解决的三个真实问题第一个问题是“这条规则到底叫什么”。我只记得项目里报了一个和 unused import 有关的错误但不确定代码是F401还是其它这时直接在ruff list --select F的输出里找名字比打开文档搜更快。第二个问题是“哪些规则属于这一类”。想把所有“导入相关”的规则一口气看完就可以ruff list --select E4, I结果会直接给你分好组不用挨个猜。第三个问题是“哪些规则能被自动修复”。虽然ruff check --fix可以一键修但如果你想在接入前先评估修复范围直接看 list 输出里的 fix 标记再结合 JSON 格式二次筛选效率会高很多。说白了list 就是规则目录查询接口--select N就是缩小目录范围的关键词查询参数。在命令行里做规则治理这是最顺手的一步。2. --select N 的筛选逻辑N 不只是数字2.1 N 的三种写法前缀、全码、规则名--select N里的 N 在 ruff 里叫 selector它有三种常见写法很多人只知道第一种。第一种是大类前缀比如ruff list --select F这时列出的是F1、F2、F4、F5等所有以 F 开头的子类下全部规则。适合你想看某一个领域内的全部规则比如 Pyflakes 检查的未定义变量、未使用导入等问题。第二种是子类前缀比如ruff list --select E4这时只显示E401、E402这类和导入相关的规则。粒度比大类细比单条规则粗。实际排查问题的时候我经常先按子类前缀缩小范围再定位具体规则号。第三种是完整规则号或规则名比如ruff list --select E501 ruff list --select line-too-long两种写法等效。E501是规则号line-too-long是这条规则的标准名字。规则名的好处是见名知意适合你不确定编号但清楚想查什么功能的时候用。这三种写法可以混着传用逗号分隔即可ruff list --select E501, F401, I001这里要提醒一句--select的解析是大小写敏感的。E501和e501不是一回事写错了不会报错但你会拿到一个空列表误以为命令没生效。2.2 多选择器组合时的取并集逻辑--select传入多个选择器时规则只要匹配任意一个就会被显示也就是取并集。举个例子ruff list --select F, E4, SIM输出里可能同时包含 Pyflakes 类、导入错误类、以及 flake8-simplify 的规则。这个设计很符合查目录的习惯你不想多次执行命令只想一次性浏览交叉领域。如果你反过来想“排除一部分规则”list 命令也支持--ignore参数。比如ruff list --select E --ignore E501这样就是先选出 E 类全部规则再从中把E501摘掉。说实话直接--select E4,E5,E7,E8...也不是不行但写起来又臭又长。能用--ignore表达清楚的事情就不要手动去拼列表。还有一个使用细节当--select和--ignore同时出现时ruff 会先按--select圈定候选集再用--ignore剔除。理解这个顺序排查“为什么少了某条规则”时会省很多力气。2.3 别和 check 命令的 --select 混在一起这是新人在命令行里最常踩的坑ruff list --select E501只是把E501这条规则显示给你看它不会去扫描代码更不会修改文件。ruff check --select E501才是真正开启这条规则并对项目代码执行检查。打个比方list 像菜谱目录check 像真正按菜谱炒菜。你在菜谱里查“红烧肉”不会让厨房里多出一道菜同样你在 list 里筛出E501也不会让 lint 开始报行过长。但这并不意味着 list 的过滤结果没有参考价值。我一般先通过 list 确定规则目录再把这批规则号整理进pyproject.toml的:[tool.ruff.lint] select [E, F, I, SIM]这两个场景是联动的list 相当于“选品”check 相当于“执行”。搞清楚了这一层你就不会在使用时纠结“为什么 list 完之后检查结果没变化”。3. 在真实项目里实操 list --select3.1 从大量规则列表里找到一条具体规则假设你看到 CI 日志里报E501 line too long你想看看这条规则是否在某个大类下或者想知道有没有相关变体。打开终端进入项目管理目录ruff list --select E501输出大致是一个规则目录表包含规则的 selectors、code、name、是否需要 Python 版本、是否可修复等信息。以本地实际版本为准。如果什么都查不到先检查一下你输入的规则号有没有写错或者当前 ruff 版本是否内置这条规则。想查得更宽一点比如“所有行长度相关的规则”可以这样ruff list --select E50E50是子类前缀比直接只看E501多了上下文的把握。你会发现行长度相关规则可能不止E501还有注释里的行长度限制等。这个习惯能帮你把“查一条规则”升级成“理解一组规则”。3.2 按工作场景筛选规则集合不同的工作场景我会用不同的选择器组合这里分享几个常用的场景一新项目想启用“导入排序 基础语法”检查ruff list --select I, F先看看这两类规则包含的所有条目确认没有遗漏后再把对应的选择器写进配置文件。场景二只想关注“代码风格错误”而暂时不管其它ruff list --select E --ignore E501, E4效果是先选 E 大类的全部规则再剔除行长度、导入布局等容易产生噪音的规则。适合做代码评审时只跑一部分风格检查。场景三排查可自动修复的规则ruff list --select F --output-format json用 JSON 格式输出后再用命令行工具或脚本筛选 fixable 字段为 true 的项。这样可以评估哪些规则能在接入后一键自动处理省去大量手工修改。这三种组合的本质都是把 list 当作“规则归档查询器”使用。你不需要记住所有规则只需要会查。3.3 用 JSON 格式做二次筛选与统计--output-format json是 list 命令容易被忽略的宝藏参数。普通文本格式适合肉眼扫但如果你想复制粘贴、统计、或者接进脚本流程JSON 是更好的选择。简单演示一下你先执行ruff list --select F, E --output-format json rules.json然后可以用任意熟悉的工具处理。比如读取 JSON统计每个大类下可修复的规则数量或者按是否可修复筛选规则号import json with open(rules.json, encodingutf-8) as f: rules json.load(f) fixable_rules [rule[code] for rule in rules if rule.get(fixable)] print(len(fixable_rules))实际字段名以你本地的 JSON 输出为准我见过不同小版本之间字段名会有微调。所以脚本最好在运行时先打印一条记录看看结构。这个技巧在实际落地时特别好用。比如你想在团队规范里宣布“我们启用了这些规则”手抄一条条规则号很容易漏直接跑一个 JSON 筛选再自动生成配置就不会出错。3.4 把筛选结果落进项目配置文件筛选规则最终还是要落到配置里否则 list 查完就只是信息不产生规范约束。常见的配置路径是pyproject.toml示例如下[tool.ruff.lint] select [ E, # pycodestyle Errors F, # Pyflakes I, # isort SIM, # flake8-simplify ] [tool.ruff.lint.per-file-ignores] tests/**/*.py [E501]在写入配置前我非常建议先跑一条命令验证你的选择器写法能被 ruff 正确解析ruff list --select E, F, I, SIM --output-format text | head -n 20如果你之前没见过这些名称先看看列表是否符合预期再进配置文件。配好之后跑一次ruff check .确认没有出现“unused rule selector”这类提示。这样 list 和 check 就形成了闭环目录查询帮助制定配置配置反哺实际检查。4. 常见问题与排查技巧实录4.1 三个最常见的理解偏差第一个偏差以为ruff list --select E会修改项目配置。实际它只是查目录不会写任何文件。你查完规则还是要自己动手改pyproject.toml或者命令行参数。第二个偏差以为 list 会读取当前项目的已启规则只显示已启用的那部分。实际 list 更多展示的是 ruff 内置规则集中符合你筛选条件的全部规则。查看已启用规则时应该去看ruff check --show-settings或插件提供的信息。如果发现 list 显示的规则远多于实际启用规则不要惊讶这是目录查询的设计。第三个偏差以为规则号一定连续、一定存在。实际上E502、E504可能不存在E509可能也会缺位。规则之间的空号是历史遗留不代表你的命令出了问题。如果想让输出干净一点加上ruff list --select E --no-cache缓存问题少但我在升级 ruff 后遇到过 list 输出旧规则集的情况这个参数能强制绕过缓存排查异常时值得一试。4.2 参数不生效、输出为空怎么排查命令查不到规则时别急着怪工具。按这个顺序排查第一步确认你有没有写对选择器。ruff list --select E501和ruff list --select E051前者正常后者大概率为空。看目录时注意规则号前导零E 类规则常写成 E501 而不是 E0501两者前缀不同。第二步确认当前 ruff 版本是否支持该规则。ruff --version再把这个规则号放到官方文档搜索框里查或者直接打开配置文件看有没有对应的插件依赖。第三方插件提供的规则不会默认内置没装对应插件时 list 自然搜不到。第三步看看是不是大小写问题。ruff list --select f401改成ruff list --select F401大小写错误不会报错但会静默返回空列表。命令行工具有时就是这样报错比“没结果”更友好。第四步检查命令的输出格式是否是 text避免 JSON 输出打乱你的视觉排查。4.3 版本差异与第三方插件的影响ruff 发展很快规则集也在持续演进。你今天在ruff list里看到的一条规则在半年后的版本里可能改了名称、被合并成别的规则或者需要开启 preview 才能查询。遇到这种情况我建议先ruff list --select RP看看与 preview 相关的规则是否存在以及当前版本是否默认展示。有些规则必须在配置中开启 preview 后才出现在 list 里这是最新几个版本里比较明显的行为变化。第三方插件方面比如 flake8-bandit、flake8-bugbear 的类型ruff 通过内置或配置实现并不与 flake8 插件共用同一个包名。所以你在 list 里找不到某个 flake8 插件规则时先确认是否已经通过[tool.ruff.lint] extend-select或插件列表启用了对应来源。有一个土办法比较直观直接在项目里跑ruff check --select B001 --ignore ALL .如果 B001 是内置规则它会参与检查如果提示无法识别或未启用那它可能来自某个你还没接入的插件来源。当然这只是排查思路真正确认还是要看文档和ruff rule B001的输出。4.4 常用筛选命令速查表这里整理一份我自己常放在终端备忘里的对照表方便你快速查找需求命令示例说明查看某个大类全部规则ruff list --select F列出 Pyflakes 类全部规则查看子类规则ruff list --select E4只看导入相关规则查询单条规则详情ruff list --select E501精确显示 E501 一条查规则名对应的编号ruff list --select line-too-long用规则名反查规则号多类规则一起看ruff list --select F, I, SIM返回多个选择器并集先选再剔除ruff list --select E --ignore E501E 类中排除 E501查看单条规则完整说明ruff rule E501比 list 更详细的文档级输出以 JSON 格式导出ruff list --select F --output-format json方便脚本或二次统计表格里多出来的ruff rule E501是我特别想推荐的命令。list 告诉你规则在目录里rule 告诉你这条规则具体怎么理解、有哪些配置参数、示例是什么样的。两者配合基本能解决规则调研 80% 的需求。5. 这条命令在命令行工作流里的位置如果你和我一样经常在终端里处理多个 Python 项目ruff list --select N应该被纳入“规则治理”工具箱而不是把它当成一个偶尔好奇时才摸一下的命令。我的习惯是新接一个仓库先跑ruff list --select F, E, I看看现有规则覆盖面遇到 CI 报错先跑ruff rule 规则号理解报错意图要调整规范时再跑ruff list --select 选择器验证哪些规则会进入配置。这样一来命令行就不只是“跑检查”的地方而是变成了一个可以自由查询规则目录的交互环境。你会慢慢发现几乎所有 lint 规则问题都可以转化为“选择器 查询 验证”三步。选择器负责缩小范围list 命令负责展示结构ruff check负责最终验证。三步走完规则配置基本不会跑偏。最后分享一个小技巧如果你经常要在不同项目里对比规则集可以先把当前项目的规则列表导出成文件ruff list --select E, F, I, SIM --output-format json rules-backup.json之后再升级 ruff 或调整依赖直接 diff 这个文件就能清楚看到规则集发生了哪些变化。这个方法比肉眼翻文档靠谱得多也适合在团队里做规则变更记录。命令行工具的乐趣就在于这些细微但扎实的效率提升。