Ruff 的主要优势是其用 Rust 编写,性能远超基于 Python 的 Linter。
🚀 Ruff 的安装与使用
1. 安装
Ruff 是一个标准的 Python 包,你可以使用 pip 进行安装:
Bash
pip install ruff
2. 基本使用
安装完成后,你可以在你的项目目录下运行 ruff 命令:
-
检查 (Lint) :运行 Linter 检查代码中的问题。
bashruff check . -
自动修复 (Fix) :Ruff 可以自动修复很多类型的问题(如未使用的导入、风格问题)。
bashruff check --fix . -
格式化 (Format) :Ruff 内置了 Formatter 功能,你可以用它替代 Black。
bashruff format .
⚙️ Ruff 的配置
Ruff 的配置非常灵活,它可以读取多种配置文件,包括 pyproject.toml(推荐 )、ruff.toml,或者直接在 setup.cfg 中配置。
推荐使用 pyproject.toml,因为它也是配置其他 Python 工具(如 Black、mypy)的标准方式。
推荐的 pyproject.toml 配置示例
toml
# pyproject.toml
[tool.ruff]
# 1. 配置规则集 (Select Rules)
# 启用所有 Flake8 的规则 (E, F, W), 以及常用的其他规则集:
# I: isort (导入排序)
# D: pydocstyle (文档字符串风格)
# C4: flake8-comprehensions (列表/字典推导式优化)
# SIM: flake8-simplify (简化代码)
# S: flake8-bandit (安全检查,不全面但可用)
# UP: pyupgrade (升级Python语法)
select = [
"E", # Flake8 Error
"F", # Pyflakes
"W", # Flake8 Warning
"I", # isort
"D", # pydocstyle
"C4", # flake8-comprehensions
"SIM", # flake8-simplify
"S", # flake8-bandit (基础安全)
"UP", # pyupgrade
]
# 2. 忽略规则 (Ignore Rules)
# 忽略一些你不希望执行的规则。
# E501: 忽略行长检查 (交给 Formatter/Black 处理)
# D100, D104: 忽略缺少模块/包文档字符串
ignore = ["E501", "D100", "D104"]
# 3. 文件排除 (Exclude Files)
# 排除不需要检查的文件或目录。
exclude = [
".venv",
"venv",
"tests/fixtures",
"docs",
]
# 4. 配置行长度 (Line Length)
line-length = 88 # 推荐使用 Black 默认的 88 字符
# 5. 配置文档字符串规则 (D-rules)
[tool.ruff.pydocstyle]
# 设置文档字符串的风格,例如 Google 风格或 NumPy 风格。
convention = "google"
# 6. 配置导入排序 (I-rules)
[tool.ruff.isort]
# 启用相对导入在本地模块中的分组
relative-imports-order = "closest-to-furthest"
# 7. 配置 Type Checking (可选)
[tool.ruff.mccabe]
# 配置最大圈复杂度,超过该值 Ruff 会报错 (默认 10)
max-complexity = 15
# 8. 格式化配置 (Formatter Configuration)
[tool.ruff.format]
# 格式化器的配置通常很少,因为它遵循 Black 的风格。
# quote-style = "single" # 强制单引号
关键配置项说明
select:这是最重要的配置项。你通过添加规则前缀 来启用 Linter 检查集。例如,E启用所有 PEP 8 错误,I启用导入排序检查。ignore:用来禁用特定的规则。例如,如果你使用了 Ruff 的 Formatter 或 Black,你可以忽略E501(行长检查),让 Formatter 处理。line-length:设置代码行的最大长度,建议与你使用的 Formatter(如 Black)的设置保持一致。
上述配置中忽略一些 Linter 规则,并交给 Formatter/Black 处理 ,是因为这些规则是关于代码风格和格式 的,它们涉及的是代码的外观 ,而不是逻辑正确性或潜在的 Bug。
🧐 为什么 Linter 规则需要被忽略?
Linter (如 Flake8, Pylint, Ruff) 的默认规则集非常庞大,其中一部分规则是关于代码风格 的,最典型的是 PEP 8 中规定的格式问题。
1. 避免工具冲突和冗余
当你在项目中使用 Formatter (如 Black 或 Ruff 的内置 Formatter)时,你就指定了代码风格的唯一权威。
- Linter 的问题: Linter 会检查并报告所有不符合它所理解的风格规范的代码。例如,Flake8 的
E501(行长度超标) 规则。 - Formatter 的处理: Formatter 的作用就是自动修正这些风格问题,使其符合一致的、预设的风格(例如,Black 默认行长 88)。
如果你不忽略这些风格规则,会出现以下问题:
- Linter 报警,但 Formatter 会修复。 这导致你每次运行 Linter 都会收到大量关于风格的警告或错误,但这些警告和错误在你运行 Formatter 后就会消失,浪费时间和注意力。
- 配置冲突。 Formatter 通常只有一套固定的、不可配置的风格(例如 Black 的"不妥协"风格)。如果你在 Linter 中配置了与 Formatter 不同的风格规则,Linter 就会一直报错,但 Formatter 会强制将其改回来,造成混乱。
2. 专注于更高价值的检查
将格式问题交给 Formatter 后,Linter 就可以专注于其更高价值的核心功能:
- 发现 Bug:如未使用的变量、未定义的名称、不安全的默认参数等。
- 提高代码质量:如检测高圈复杂度、冗余代码等。
通过忽略风格规则,你可以让 Linter 的输出变得更简洁、更有意义,只显示那些需要你手动修复以提高代码健壮性的问题。
🏷️ 典型的被忽略规则
最常见且强烈建议被忽略的规则是:
| 规则代码 | Linter 名称 | 描述 | Formatter 如何处理 | 为什么忽略 |
|---|---|---|---|---|
E501 |
Flake8/PEP 8 | 行长度超过最大限制。 | Formatter 会自动换行和重新排版,确保不超限(Black 默认 88 字符)。 | 避免风格冲突,将排版权威交给 Formatter。 |
W503/W504 |
Flake8/PEP 8 | 二元运算符(如 +, -)应在行尾还是行首。 |
Formatter 会统一选择一种风格并自动应用。 | 纯粹的风格问题,不影响逻辑,让 Formatter 统一。 |
I001 |
isort | 导入未排序 (Ruff 内置了 isort 规则 I)。 |
Formatter/Ruff Formatter 会自动对导入进行分组和排序。 | Formatter 已经包含了此功能,Linter 冗余。 |
Formatter 解决了"代码看起来怎么样"的问题,而 Linter 解决了"代码能否正确且高效地运行"的问题。忽略 Linter 的格式规则,可以确保这两者的职责清晰分离。