isort 井井有条 —— Python 导入格式化工具
本文最后更新于 2022年5月26日 下午
在上一篇《五彩斑斓的 Black —— Python 代码格式化工具》中介绍了如何利用工具将代码格式化至整齐统一的风格,这次再来介绍一个工具,可以把我们的 import 语句格式化至井井有条,那就是 isort 。
简介
isort 是一个实用的 Python 程序/库,用于按照字母表顺序对 imports 进行排序,并自动按类型(标准库/第三方库/自己的模块/……)划分部分。它为各种编辑器提供了命令行程序、Python 库和插件,以快速对所有导入进行排序。需要 Python 3.6 + ,但也支持 Python 2 。
来看官网提供的例子:
1 |
|
使用 isort 格式化后:
1 |
|
import 部分明显清爽、有条理了许多。
安装
安装非常简单,只需:
1 |
|
安装 isort 并支持 requirements.txt :
1 |
|
带 Pipfile 支持的 isort 安装:
1 |
|
支持两种格式的 isort 安装:
1 |
|
Tip
如果您希望 isort 作为项目的 linter,则可能需要为每个使用它的项目添加 isort 作为显示开发依赖项。另一方面,如果您是个人开发人员,只是使用 isort 作为个人工具来清理您自己的 commit ,那么全局或用户级别的安装是有意义的。两者都在一台机器上无缝支持。
简单使用
命令行使用
在特定文件上运行:
1 |
|
递归地使用:
1 |
|
如果开启了 globstar ,则isort .
等价于:
1 |
|
仅查看 isort 将做出的变更,但并不应用:
1 |
|
以原子方式对项目运行 isort,仅在不引入语法错误的情况下应用更改:
1 |
|
(注意:默认情况下这是禁用的,因为它可以防止 isort 针对使用不同版本的 Python 编写的代码运行。)
更多选项可参阅本文命令行选项一节。
在 Python 内使用
1 |
|
或者
1 |
|
更多信息可参阅本文 Python API 一节。
集成至IDE / 编辑器中
在 isort Wiki 可以查看所有 isort 插件。
在 PyCharm 中使用
可以通过「外部工具」的方式将 isort 集成到 PyCharm 中。
确认 isort 安装位置
在 macOS / Linux 上:
1 |
|
类似的,在 Windows 上可以使用 where isort
命令查找。
在 PyCahrm 中添加外部工具
打开 文件 -> 设置 -> 工具 -> 外部工具
File -> Settings -> Tools -> External Tools
创建工具
- 名称:isort
- 描述:isort your imports, so you don’t have to.
- 程序:「上一小节得到的安装位置」
- 参数:
$FilePath$
- 工作目录:
$ProjectFileDir$
如果需要自定义其他选项,写在 $FilePath$
前即可。
使用
在已经打开的代码编辑界面(或项目文件树的某个目录上)鼠标右键,找到 External Tools -> isort,点击即可。
使用 File Watcher (可选)
除了外部工具这种方式,还可以通过 File Watchers 插件使用 isort 。
安装插件后,进入 设置 -> 工具 -> File Watchers,点击 + 以添加一个新的 watcher:
- Name: isort
- File Type: Python
- Scope: Project Files
- Program:
$PyInterpreterDirectory$/python
- Arguments:
-m isort $FilePath$
- Output paths to refresh:
$FilePath$
- Working directory:
$ProjectFileDir$
- In Advanced Options
- 取消勾选 “Auto-save edited files to trigger the watcher”
- 取消勾选 “Trigger the watcher on external changes”
一点补充
PyCharm 中其实已经内置了自动 import 优化工具。类似于使用 Black 替代内置代码格式化工具的做法,使用 isort 的意义很大程度上在于保持统一。这样在团队协作中,即使有的开发者并不使用 PyCahrm 编辑代码,也可以通过相同配置文件的 isort 确保代码导入风格完全相同。
在 VS Code 中使用
安装 Python 插件
首先确保已经在 VS Code 中安装了 Python 插件。如果没有安装,则在 VS Code 中按下 Ctrl + P
,并输入如下命令:
1 |
|
或者直接在扩展商店中搜索 Python 并安装。
配置选项
按下 Ctrl + ,
,打开 VS Code 设置
在「设置」中搜索 python sort imports ,然后设置一下 isort 脚本位置。例如在我的机器上:
1 |
|
如果不手动设置 isort 路径,Python 插件将使用其内置的 isort ,目前的版本为 isort==5.10.1 ,已经是最新的 isort 版本。
如果需要使用 isort 的自定义选项,在第一行那里「添加项」即可。
使用
直接在已经打开的 Python 文件编辑窗口中点击鼠标右键,弹出的菜单中选择「排序 import 语句」即可。
使用 isort 扩展
目前,微软官方出品的 isort 扩展 已作为预发布版本上线扩展商店,待其转为正式发布版,本文将同步更新。
详细使用
命令行选项
完整的选项列表和说明可参阅官方文档:「Configuration options for isort」
isort 的命令行选项非常多,这里仅列出了 isort --help 返回的帮助文档中的 general options 部分的内容,并尽我所能做了翻译:
1 |
|
添加/移除 Imports
本节翻译自官方文档 「Add Or Remove Imports」
向多个文件中添加一个 import
isort 可以很容易地在多个文件中添加导入语句,同时确保它被正确放置。
向所有文件中添加一个 import:
1 |
|
仅向已有 import 的文件中添加一个 import :
1 |
|
从多个文件中移除一个 import
isort 还可以轻松地从多个文件中删除导入,而不必关心它的原始格式。
命令行用法:
1 |
|
API
本节翻译自官方文档 「Programmatic Python API Usage」,更多 API 细节参阅API 参考文档
除了强大的命令行界面, isort 还提供了一个完整的 Python API 。
为使用 Python API ,import isort
然后调用所需要的函数。
每个函数都有完整的类型提示,并且接收和返回的都是 Python 内置对象。
主要包括:
isort.code
- 接收一个包含代码的字符串,并在对 import 排序后返回它isort.check_code
- 接收一个包含代码的字符串,如果所有 import 都已经正确排序,则返回True
,否则返回False
isort.stream
- 接收一个包含 Python 代码的输入流和一个输出流。向输出流输出已经对 import 进行了排序的代码。isort.check_stream
- 接收一个包含 Python 代码的输出流,如果所有 import 都已经正确排序,则返回True
,否则返回False
isort.file
- 接收 Python 源文件的路径,并就地对 import 进行排序isort.check_file
- 接收 Python 源文件的路径,如果所有 import 都已经正确排序,则返回True
,否则返回False
isort.place_module
- 将模块的名称作为字符串并返回为其确定的分类isort.place_module_with_reason
- 将模块的名称作为字符串并返回为其确定的分类,并给出确定该分类的原因
有关 API 的完整定义,请参阅API 参考文档,或在交互式解释器中尝试 help(isort)
。
配置文件
本节翻译自官方文档 「Supported Config Files」
isort 支持许多种标准配置格式,允许将自定义选项快速集成到任何项目中。应用配置时,iosrt 会按照下面列出的顺序查找最近的支持的配置文件。您可以通过从命令行设置 --settings-path
来手动指定设置文件或路径。否则,isort 将遍历最多 25 个父目录,直到找到合适的配置文件。注意 isort 将不会离开 git 或 Mercurial 存储库(检查 .git
或 .hg
目录)。一旦找到文件,它就会停止查找。如果传入了 .isort
或文件流,则配置文件的搜索是相对于当前目录完成的,如果传入多个路径,则是相对于传入的第一个路径。isort 永远不会把多个配置文件合并在一起,因为这可能导致混乱。
Tip
您可以随时通过运行 isort . --show-config
来内省 isort 确定的配置设置,以及找出它选择了哪个配置文件。
.isort.cfg [preferred format]
isort 将查找设置项的首要位置是在专门的 .isort.cfg 文件中。使用这种配置文件的优点是,它是明确用于 isort 的,且遵循易于理解的格式。不利的方面则在于,在您的项目(也许文件层级关系已经因为数个配置文件而有点混乱了)中又多了一个配置文件。
一个来自 isort 项目本身的例子:
1 |
|
pyproject.toml [preferred format]
isort 将要查找的第二个位置,一个同样明智的保存配置的选择,是 pyproject.toml 文件中。使用这个配置文件的好处在于,它正很快成为所有 Python 工具保存配置的标准位置。这意味着其他开发人员也会知道来这里查看,您的项目根目录将保持整洁。唯一的缺点是您使用的其他工具可能尚不支持这种格式,从而影响了清洁度。
1 |
|
setup.cfg
setup.cfg
可以被认为是 pyproject.toml
的前身。虽然 isort 和更新的工具越来越多地转移到 pyproject.toml,但如果您依赖于许多使用此标准的工具,那么将您的 isort 配置保存在那里也是自然且合适的。
1 |
|
tox.ini
tox 是 Python 社区常用的一种工具,用于指定多个测试环境。因为 isort 验证通常作为测试步骤运行,所以有些人更喜欢将 isort 配置放在 tox.ini 文件中。
1 |
|
.editorconfig
最后,isort 将查找带有 Python 源文件设置的 .editorconfig
配置。EditorConfig 是一个项目,可以为文本编辑器行为指定一次配置,允许多个命令行工具和文本编辑器选用它。由于 isort 关心许多和文本编辑器相同的设置(如行长度),因此它也会在这些文件中查找。
Custom config files
可选的,您还可以使用 --settings-file
创建具有自定义名称的配置文件,或者直接将 isort 引导至优先级顺序较低的配置文件。这可能很有用,例如,如果您想为 .py 文件设置一个配置,为 .pyx 设置另一个配置——同时将配置文件保留在存储库的根目录中。
Tip
自定义配置文件应该将它们的配置选项放在 [isort]
部分而不是通用的 [settings]
部分。这是因为 isort 无法确定其他工具如何使用配置文件。
自定义与行为控制
Action 注释
本节翻译自官方文档 「Action Comments」
可以通过 Python 代码中的注释控制 isort 的行为。
isort: skip_file
让 isort 跳过整个文件。
例子:
1 |
|
Warning
这应该尽可能合理地放在文件的最上面。由于 isort 使用的是流式架构,它可能在读到该行注释之前就已经完成了一些工作。一般情况下问题不大,但如果从命令行使用 --diff
或任何交互式选项,则可能造成混乱。
isort: skip
如果将其放在与 import 语句同一行中,则 isort 将不会对此 import 进行排序。更具体地说,它会阻止 import 语句被 isort 识别为 import 。因此,这一行将被视为代码并被推到文件导入部分的下方。
例子:
1 |
|
Note:
建议尽可能使用 # isort: off
和 # isort: on
或 isort: split
来替代,这样行为更明确和可预测。
isort: off
关闭 isort 解析。# isort: off
语句之后的每一行都将保持不变,直到 # isort: on
注释或文件结束。
例子:
1 |
|
isort: on
重新打开 isort 解析。这仅在文件上文中存在 isort: off
注释时才有意义!这允许您在其他已排序的导入块周围存在未排序的导入块。
例子:
1 |
|
isort: split
告知 isort 当前排序部分已完成,所有未来的 import 都属于新的排序分组。
例子:
1 |
|
您还可以内联使用它,来防止 import 在其上方或下方交换位置:
1 |
|
Tip
isort split 与在 # isort: off
下一行放置 # isort: on
的效果完全相同。
isort: dont-add-imports
告诉 isort 不自动向这个文件添加 import ,即使已经设置了 --add-imports 。
isort: dont-add-import: [IMPORT_LINE]
告诉 isort 不要自动添加特定的导入,即使 --add-imports 说明了要添加它。
自定义「部分」与排序
本节翻译自官方文档 「Custom Sections and Ordering」
isort 提供了许多功能来配置它如何对导入划分「部分」(section),及如何在这些「部分」内对导入排序。您可以使用 sections
选项来改变「部分」间的顺序,从默认值:
1 |
|
改为您的喜好(如果已定义,省略一个默认「部分」可能会导致错误):
1 |
|
您也可以定义您自己的「部分」划分及其顺序。
例如:
1 |
|
将使用指定的已知模块创建两个「部分」。
no_lines_before
选项将防止列出的「部分」被空行与上一个「部分」分开。
例如:
1 |
|
将产生一个结合了 FIRSTPARTY 和 LOCALFOLDER 模块的「部分」。
重要提示:在设置 known
「部分」时,了解由于历史原因不是直接映射的命名非常重要。对于自定义设置,唯一的区别是大小写(known_custom=custom
VS sections=CUSTOM,...
),其他所有引用按如下方式映射:
known_standard_library
:STANDARD_LIBRARY
extra_standard_library
:STANDARD_LIBRARY
# 类似已知标准库,但附加而不是替换known_future_library
:FUTURE
known_first_party
:FIRSTPARTY
known_third_party
:THIRDPARTY
known_local_folder
:LOCALFOLDER
这可能会在 isort 6.0.0+ 中以向后兼容的方式进行更改。
对 import 各「部分」自动注释
一些项目更倾向于让每个导入「部分」具有独有的标题,以辅助在扫视时快速识别这些「部分」。isort 也可以自动执行此操作。为此,您只需简单地将每一个您想要设置自动注释的「部分」的 import_heading_{section_name}
设置为所需的注释。
举例来说:
1 |
|
将会导致输出如下所示:
1 |
|
按 import 长度排序
isort 还可以轻松按长度对导入进行排序,只需将 length_sort
选项设置为 True
。这将导致以下输出样式:
1 |
|
也可以通过使用 length_sort_
后跟「部分」名称作为配置项,来选择仅对特定节按导入的长度进行排序,例如:
1 |
|
控制 isort 如何处理 from
导入「部分」
默认情况下,isort 将直接导入(import y
)放在 from 导入(from x import y
)的上面:
1 |
|
但是,如果您更喜欢严格按照字母顺序排序,您可以将 force sort within sections 设置为 true。结果是:
1 |
|
您甚至可以使用from first 告知 isort 始终将 from 导入放在顶部,而不是默认放在底部:
1 |
|
多行输出模式
本节翻译自官方文档 「Multi Line Output Modes」
此配置选项定义了当 from imports 超出 line_length 限制时如何换行,共有 12 种可选的设置:
0 - Grid
网格
1 |
|
1 - Vertical
垂直
1 |
|
2 - Hanging Indent
悬挂缩进
1 |
|
3 - Vertical Hanging Indent
垂直悬挂缩进
1 |
|
4 - Hanging Grid
悬挂网格
1 |
|
5 - Hanging Grid Grouped
分组悬挂网格
1 |
|
6 - Hanging Grid Grouped
与模式 5 相同
7 - NOQA
1 |
|
或者,您可以将 force_single_line
设置为 True
(命令行上的 -sl
),然后每个 import 都会出现在自己的行上:
1 |
|
8 - Vertical Hanging Indent Bracket
括号垂直悬挂缩进
和 模式 3 - 垂直悬挂缩进相同,但最后一行的右括号缩进。
1 |
|
9 - Vertical Prefix From Module Import
from MODULE import 垂直前缀
当行的长度大于长度限制时,以相同的 from MODULE import
前缀开始一个新行。
1 |
|
10 - Hanging Indent With Parentheses
带括号的悬挂缩进
与模式 2 - 悬挂缩进相同,但使用括号而不是反斜杠来包裹长行。
1 |
|
11 - Backslash Grid
反斜杠网格
与模式 0 - 网格相同,但使用反斜杠而不是括号对导入进行分组。
1 |
|
协同工作与合入工作流程
与 Black 协同
本节翻译自官方文档 「Compatibility with black」
isort 的代码本身就是使用了 Black 来做代码格式化的。其官方文档也高调宣告了两者的亲密关系。
与 Black 的兼容性对于 isort 项目非常重要,并且从版本 5 就开始了。将 isort 和 Black 协同使用所需的一切操作仅为将 isort 配置文件设置为 “black”。
Tip
除了配置文件之外,通常还需要设置 skip_gitignore (默认情况下不为 isort 启用,因为它需要已经安装了 git)和 line_length(因为它通常偏离 Black 的默认值 88)。
使用配置文件(例如 .isort.cfg)
对于正式同时使用 isort 和 Black 的项目,我们建议在项目仓库根目录下的配置文件中设置 Black 配置文件。这样,它与用户如何调用 isort(pre-commit、命令行、或者编辑器集成)无关,Black 配置文件都会自动应用。
例如,您的 pyproject.toml 文件看起来会像这样:
1 |
|
参阅有关支持的配置文件的更多信息。
命令行界面
要在直接从命令行调用 isort 时使用配置文件选项,只需添加 --profile black 选项:isort --profile black
一个 .travis.yml 的例子:
1 |
|
有关更多配置文件的信息,请参阅内置配置文件。
与 pre-commit 协同
本节翻译自官方文档 「Using isort with pre-commit」
isort 提供对 pre-commit 的官方支持。
isort pre-commit 步骤
为使用 isort 的官方 pre-commit 集成,请添加以下配置:
1 |
|
放在在您项目的 .pre-commit-config.yaml
文件中 repos
部分下面。
seed-isort-config
旧版本的 isort 使用了大量魔术方法来确定导入位置,在 CI/CD 上运行时很容易中断。为了解决这个问题,创建了一个名为 seed-isort-config
的实用程序。然而自 isort 5 以来,项目已经大大改进了其放置逻辑,并确保了良好的跨平台一致性。如果您的 pre-commit 配置中有一个名为 seed-isort-config
或类似的东西,强烈建议您删除它。这一定会减慢速度,并且可能与 isort 自己的模块放置逻辑发生冲突。
Git Hook
本节翻译自官方文档 「Git Hook」
isort 提供了一个钩子函数,可以集成到你的 Git pre-commit 脚本中,以在 commit 之前检查 Python 代码。
为实现如果存在 isort 错误(严格模式),将导致 commit 失败,请在 .git/hooks/pre-commit
中包含以下内容:
1 |
|
如果您只想显示警告,但无论如何都允许 commit ,请在不带 strict 参数的情况下调用 git_hook
。如果您想显示警告,但又不想修复代码,请在不带 modify 参数的情况下调用 git_hook
。lazy
参数用于支持倾向于使用 git commit -a
而不是将文件单独添加到索引中的“懒惰”的用户。将其设置为 True
以确保所有跟踪的文件都被正确 isort ,将其忽略或设置为 False
以仅检查添加到索引中的文件。
如果要为钩子使用特定的配置文件,可以将其路径传递给 settings_file 。如果没有特别指定路径,git_hook
将从包含第一个暂存文件的目录开始搜索配置文件,即按照每个 git diff-index
的顺序,然后向上级目录结构搜索,直到找到一个有效的配置文件,或已经检查了 MAX_CONFIG_SEARCH_DEPTH
深度的目录为止。settings_file 参数用于支持将配置文件保存在可能不是其他文件的父目录中的用户。
GitHub Actions
本节翻译自官方文档 「Github Action」
isort 提供了一个官方 Github Action ,可用作 CI/CD 工作流程的一部分,以确保项目的导入正确排序。该 action 可以在 Github Actions Marketplace 上找到。
python-isort
插件旨在与 checkout
和 setup-python
操作组合运行。默认情况下,它将从被 linted 的存储库的根目录递归运行,如果代码未能正确排序,它将退出并显示错误。
输入
isortVersion
可选项。要使用的 isort
版本。默认为最新版的 isort
。
sortPaths
可选项。要排序的路径列表,相对于您的项目根目录。默认为 .
。
configuration
可选项。isort
配置选项传递给 isort
命令行。默认为 --check-only --diff
。
requirementsFiles
可选项。在运行 isort 之前要安装的 Python 需求文件的路径。如果提供了多个需求文件,它们之间应该用空格隔开。如果需要自定义包安装,则在使用此操作之前应在单独的步骤中安装依赖项。
Tip
在运行 isort 之前安装项目的依赖项很重要,以便正确排序第三方库。
输出
isort-result
isort
命令行输出
使用举例
1 |
|
Setuptools 整合
本节翻译自官方文档 「Setuptools integration」
安装后,isort 启用一个 setuptools
命令,用于检查您的项目声明的 Python 文件。
在命令行上运行 python setup.py isort
将检查您的 py_modules
和 packages
中列出的文件。如果发现任何警告,该命令将以错误代码退出:
1 |
|
此外,为了允许用户无需自己安装 isort 即可使用该命令,请将 isort 添加到 setup()
的 setup_requires 中,如下所示:
1 |
|
其他
在 README 中展示
如果你的项目使用了 isort 工具,可以在 README.md 中加入下面一行:
1 |
|
报告安全漏洞
要报告安全漏洞,请使用 Tidelift security contact 。Tidelift 将协调修复和披露。