Skip to content

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 工具的功能设计存在重要区别:

  1. 格式化(formatter)ruff format 仅重新排版已有导入(保持位置),但不重组或重新排序
  2. 检查(linter):导入排序和分类属于 lint 功能,需通过 ruff check 实现

这种设计确保格式化器不改变程序的 AST(抽象语法树)结构,保持语义行为不变。

解决方案

方法一:命令行执行(推荐)

运行以下命令组合:

bash
# 第一步:修复导入排序
ruff check --select I --fix

# 第二步:格式化代码(可选)
ruff format

说明

  • --select I 表示针对所有以 "I" 开头的规则(导入相关规则)
  • --fix 参数自动修复可修正的问题
  • 单独执行 ruff check --select I --fix 即可完成排序

方法二:永久配置

编辑配置文件(pyproject.tomlruff.toml):

toml
# 启用所有导入相关规则
extend-select = ["I"]

之后只需运行单个指令:

bash
ruff check --fix

实际效果对比

原始代码:

python
import os
import collections

正确执行后变为:

python
import collections
import os

注意

常见疑问

为何设计成两步操作?

  • Ruff 严格分离重构行为(改变语义)和格式化(保持语义)
  • 此架构避免意外修改程序逻辑,提高可靠性
  • 开发团队正在讨论优化方案,未来可能整合流程

与 isort 有何差异?

项目isortruff
排序触发方式独立命令check --fix
代码格式化需配合 blackruff format
配置兼容性自定义配置兼容 isort 预设

最佳实践

建议完整工作流:

bash
# 1. 修复导入排序
ruff check --select I --fix

# 2. 格式化整个代码库
ruff format

# 3. 检查其他问题
ruff check --fix

此流程兼顾导入排序、代码格式化和全面静态检查