# 深入理解 Python isort一个不太起眼但非常有用的工具写 Python 代码的时候我们每天都在跟 import 语句打交道。看起来就是把需要的模块引进来但实际上import 的排列方式有时候会让人很头疼。特别是团队协作的时候每个人写 import 的习惯都不一样有人喜欢按字母排序有人喜欢把标准库和第三方库分开还有人喜欢把相对导入和绝对导入混在一起。时间久了代码仓库里的 import 部分就变得乱七八糟的。这里想聊一个专门解决这个问题的工具 —— isort。它不像 Flask、Django 那样名声在外但在日常开发中它解决的问题其实非常实在。isort 是什么isort 的全称是 “Import Sorter”导入排序器。从名字就能看出来它的核心功能就是整理 Python 文件中的 import 语句。但如果你以为它只是简单的排个序那就太小看它了。这个工具其实是一个 Python 实用工具它可以自动对 import 进行排序、分组和格式化。它遵循的是 PEP8 的建议 —— 把 import 分成三个部分标准库、第三方库、本地库并且每组之间用空行隔开。但 isort 做的事情比 PEP8 建议的更加细致。它还支持多种配置方式可以适应不同项目或团队的编码规范。有意思的是isort 的开发者 Timothy Crosley 在 2013 年写了这个工具原本只是自己用后来发现很多人都遇到同样的困扰就把它开源了。现在 isort 已经成为很多 Python 项目的标配工具。它能做什么先说说 isort 能解决哪些实际问题。假设你在一个 Django 项目里工作代码中有几十个 import 语句有的来自 Django 本身有的是自己写的 models还有几个是 Python 内置的 os、sys 之类的。手动整理这些 import谁都不愿意干这个活。isort 可以在几毫秒内完成这个工作而且比手动更准确。isort 还能处理一些更复杂的场景。比如相对导入和绝对导入的处理有些项目要求统一使用绝对导入有些则允许相对导入。isort 可以根据配置决定怎么处理这些情况。再比如有些项目要求 import 不能跨行有些项目则允许长 import 拆成多行。isort 都能应对。还有一个很实用的功能是自动检测并修复重复的 import。有时候开发过程中不小心写了两次相同的 importisort 会自动合并它们。虽然看起来是个小功能但在大型项目中能减少很多潜在的错误。isort 还可以和 pre-commit 或者 CI/CD 流程集成。也就是说你可以在提交代码之前自动运行 isort或者在 CI 流水线上检查 import 的格式是否正确。这样就能保证整个团队的代码风格保持一致。怎么使用安装 isort 很简单就用 pippipinstallisort最基本的用法就是直接在终端运行isort your_file.py这样会自动对指定的 Python 文件进行 import 排序。如果想一次处理多个文件或者整个目录isort.# 处理当前目录下所有 Python 文件isort src/# 只处理 src 目录但更常见的做法是在项目里配置好规则然后一键处理。配置文件可以有几种形式在项目根目录放一个.isort.cfg文件或者在pyproject.toml、setup.cfg里添加 isort 的配置。比如一个简单的.isort.cfg文件[settings] profile black line_length 88 known_third_party django, requests known_first_party myproject这里profile black是告诉 isort 兼容 black 的格式化风格。用过 black 的朋友应该知道black 对 import 的排列有它自己的规则而 isort 可以遵循这些规则。known_third_party和known_first_party是告诉 isort 哪些库是第三方、哪些是本地的这样它才能正确分组。检查模式下可以用--check-only或者-cisort --check-only src/这样只检查 import 的格式是否正确不会真正修改文件。很适合在 CI 中使用。还有个很好用的功能是--diff参数它可以展示 isort 将会做哪些修改但实际不修改文件。这样在提交之前可以预览一下效果。最佳实践在实际项目中使用 isort有几点值得注意。第一个是 pre-commit 集成。把 isort 加入到 pre-commit hooks 中这样每次提交代码前都会自动检查并排序 import。一个典型的.pre-commit-config.yaml配置如下repos:-repo:https://github.com/PyCQA/isortrev:5.13.2hooks:-id:isortargs:[--profile,black]这样提交代码时 isort 就会自动运行不用自己操心。第二个是兼容性。isort 很流行的原因是它几乎可以和所有主流格式化工具配合使用比如 black、flake8、pylint。但要注意的是 isort 5.x 版本之后有一些 breaking changes特别是在配置方面。升级的时候需要确认配置文件是否还兼容。第三个是关于分组的细粒度控制。有些项目对 import 的分组有特殊要求比如把 Django 相关的放在一起DRF 的相关放在另一组。isort 支持自定义分组可以通过known_third_party、sections等配置来实现。还可以设置force_single_line强制每行只有一个 import或者include_tail控制 import 后面是否加空行。第四个是处理init.py 文件。init 文件里的 import 有时候比较特殊它可能包含相对导入、别名导入或者只是为了导出某些模块而写的from . import形式。isort 默认会处理这些情况但可以考虑给 init 文件单独设置配置比如使用skip __init__ True跳过某些 init 文件的检查。同类技术对比说到 import 格式化工具目前常见的有 isort、reorder-python-imports 和 autoflake 中的 import 排序功能。reorder-python-imports 是 Google 出的一个工具功能比 isort 轻量一些。它主要做的是重新排序 import但分组的逻辑相对简单。它有一个有趣的功能是自动移除不再使用的 import通过分析 AST这一点 isort 做不到。不过 reorder-python-imports 的配置方式比较原始需要手动指定哪些是第三方库而且它对相对导入的处理不如 isort 那么灵活。autoflake 是一个更全能的工具除了 import 排序它还能移除未使用的变量、移除未被引用的 import通过检测。但 autoflake 的 import 排序功能比较基础不像 isort 那样有丰富的配置选项。还有一个是 PyCQA 的 flake8-import-order它是 flake8 的一个插件只做检查不做修复。如果你的团队只用 flake8 做代码检查这个插件是很好的选择。但它不能自动排序需要人工修正。有没有更好的选择其实现在很多人把 isort 和 black 配合使用。isort 处理 import 部分black 负责其他代码格式化。两者配合得比较好isort 提供了--profile black来保证兼容 black 的风格。当然如果你用的是类似于 Ruff 这样的新一代 linting 工具它内置了 import 排序的功能虽然是模仿 isort 实现的但作为独立工具isort 仍然有它的价值。最后想说的isort 看起来只是个辅助工具但在团队协作中它解决了一个很实际的问题 —— 代码风格的统一。花时间去配置好 isort并且在 CI 中强制检查长远来看能节省很多精力。毕竟谁也不想在 code review 的时候因为 import 的顺序问题浪费时间。如果你的项目还没有使用 isort不妨试试看。它很小众但确实是个靠谱的工具。而且一旦习惯了他的工作方式回头看那些手动整理的 import 代码你会发现以前的做法有多不划算。