ruff 按字母顺序排序导入
问题描述
使用 ruff 工具时,发现无法按字母顺序自动排序 Python 导入语句。例如面对以下代码:
python
import os
import collections
运行 ruff format file.py
命令后提示文件未更改:
bash
$ ruff format file.py
1 file left unchanged
但使用 isort 工具却能正确排序:
bash
$ isort file.py
Fixing .../file.py
问题关键:为何 ruff 默认配置无法自动排序导入语句?如何正确配置实现类似 isort 的效果?
根本原因
ruff 工具的功能设计存在重要区别:
- 格式化(formatter):
ruff format
仅重新排版已有导入(保持位置),但不重组或重新排序 - 检查(linter):导入排序和分类属于 lint 功能,需通过
ruff check
实现
这种设计确保格式化器不改变程序的 AST(抽象语法树)结构,保持语义行为不变。
解决方案
方法一:命令行执行(推荐)
运行以下命令组合:
bash
# 第一步:修复导入排序
ruff check --select I --fix
# 第二步:格式化代码(可选)
ruff format
说明
--select I
表示针对所有以 "I" 开头的规则(导入相关规则)--fix
参数自动修复可修正的问题- 单独执行
ruff check --select I --fix
即可完成排序
方法二:永久配置
编辑配置文件(pyproject.toml
或 ruff.toml
):
toml
# 启用所有导入相关规则
extend-select = ["I"]
之后只需运行单个指令:
bash
ruff check --fix
实际效果对比
原始代码:
python
import os
import collections
正确执行后变为:
python
import collections
import os
注意
- Ruff 的导入排序规则默认等同于 isort 的
profile = "black"
配置 - 如需自定义排序方式,可查阅官方配置选项:
常见疑问
为何设计成两步操作?
- Ruff 严格分离重构行为(改变语义)和格式化(保持语义)
- 此架构避免意外修改程序逻辑,提高可靠性
- 开发团队正在讨论优化方案,未来可能整合流程
与 isort 有何差异?
项目 | isort | ruff |
---|---|---|
排序触发方式 | 独立命令 | check --fix |
代码格式化 | 需配合 black | ruff format |
配置兼容性 | 自定义配置 | 兼容 isort 预设 |
最佳实践
建议完整工作流:
bash
# 1. 修复导入排序
ruff check --select I --fix
# 2. 格式化整个代码库
ruff format
# 3. 检查其他问题
ruff check --fix
此流程兼顾导入排序、代码格式化和全面静态检查