Python `black` / `isort`:代码格式化与自动导入排序

好的,各位程序猿、媛们,欢迎来到今天的代码美颜课堂!今天我们要聊的是Python界的两位颜值担当:blackisort。别误会,我们不是要搞选美比赛,而是要学习如何让我们的代码像刚从Tony老师那儿出来的发型一样,整齐、规范、赏心悦目。

第一部分:black——代码界的钢铁直男

black,顾名思义,就像一个穿着黑色西装,一丝不苟的钢铁直男,它会毫不留情地把你随心所欲的代码格式,强制变成它认为最美的样子。你可能会抗议:“凭什么?我的代码我做主!”但相信我,一旦你习惯了black的审美,你会发现,真香!

1. 为什么我们需要black

  • 统一风格: 团队协作时,最怕的就是每个人都有自己的代码风格。你缩进用2个空格,他用4个,还有人用Tab!这简直是代码界的“巴别塔”。black就像一个统一的裁判,强制所有人的代码都使用相同的风格,减少撕逼的可能性。
  • 减少Code Review负担: Code Review本来就够累了,还要花时间纠结空格、换行之类的细节,简直是浪费生命。black可以自动处理这些琐碎的格式问题,让Code Reviewers可以专注于代码逻辑本身。
  • 解放大脑: 程序员的大脑是用来解决复杂问题的,而不是用来数空格的。让black来帮你处理格式问题,你可以把精力放在更重要的事情上。

2. black的安装与使用

安装black非常简单,只需要一条命令:

pip install black

安装完成后,就可以在命令行中使用black了。最简单的用法就是:

black your_code.py

这条命令会直接修改your_code.py文件,使其符合black的风格。如果你不想直接修改文件,只想看看black会怎么改,可以使用--check参数:

black --check your_code.py

如果your_code.py不符合black的风格,这条命令会返回一个非零的退出码。如果你想查看black会做哪些修改,可以使用--diff参数:

black --diff your_code.py

这条命令会显示black将对your_code.py文件进行的修改。

3. black的配置

black的配置选项不多,但也足够满足一些个性化的需求。

  • 行长度: 默认情况下,black会将代码行长度限制在88个字符。你可以使用--line-length参数来修改这个值:

    black --line-length 120 your_code.py
  • 目标Python版本: black会根据你的Python版本来格式化代码。你可以使用--target-version参数来指定目标Python版本:

    black --target-version py37 your_code.py
  • 忽略文件或目录: 你可以使用--exclude参数来忽略某些文件或目录:

    black --exclude "tests|migrations" your_code.py

    这个例子会忽略名为testsmigrations的目录。

你也可以创建一个pyproject.toml文件来配置black。例如:

[tool.black]
line-length = 120
target-version = ['py37']
exclude = 'tests|migrations'

把这个文件放在项目的根目录下,black会自动读取这些配置。

4. black示例

让我们来看一些black的实际效果。假设我们有如下代码:

def my_function(  long_argument_name_1, long_argument_name_2,
                   long_argument_name_3 ):
    if True:
        print ("Hello, world!")

使用black格式化后,代码会变成这样:

def my_function(
    long_argument_name_1,
    long_argument_name_2,
    long_argument_name_3,
):
    if True:
        print("Hello, world!")

可以看到,black自动调整了缩进、换行和空格,使代码更加清晰易读。

再看一个例子:

my_list = [1,2,3,
4,5,6]

使用black格式化后,代码会变成这样:

my_list = [1, 2, 3, 4, 5, 6]

black会自动在逗号后面添加空格。

第二部分:isort——代码界的图书管理员

isort,就像一个一丝不苟的图书管理员,它会把你的import语句按照字母顺序排列,并且按照标准库、第三方库、本地库的顺序进行分组。你可能会觉得这没什么大不了的,但相信我,一个整洁的import列表可以让你更快地找到需要的模块,并且减少代码冲突。

1. 为什么我们需要isort

  • 清晰的依赖关系: import语句是代码的依赖声明。一个整洁的import列表可以让你更容易地了解代码的依赖关系。
  • 减少代码冲突: 当多人协作时,每个人都可能添加或修改import语句。如果没有统一的规范,很容易产生代码冲突。isort可以自动解决这些冲突。
  • 提高代码可读性: 一个整洁的import列表可以让你更快地找到需要的模块,提高代码的可读性。

2. isort的安装与使用

安装isort同样简单:

pip install isort

使用isort也很简单:

isort your_code.py

这条命令会直接修改your_code.py文件,使其import语句符合isort的规范。如果你不想直接修改文件,可以使用--check参数:

isort --check your_code.py

如果your_code.pyimport语句不符合isort的规范,这条命令会返回一个非零的退出码。如果你想查看isort会做哪些修改,可以使用--diff参数:

isort --diff your_code.py

这条命令会显示isort将对your_code.py文件进行的修改。

3. isort的配置

isort的配置选项比较多,可以满足各种个性化的需求。

  • 多行import语句风格: isort支持多种多行import语句的风格,例如:

    • grid:

      from my_module import (
          long_variable_name_1,
          long_variable_name_2,
          long_variable_name_3,
      )
    • vertical:

      from my_module import (long_variable_name_1,
                             long_variable_name_2,
                             long_variable_name_3)
    • hanging_indent:

      from my_module import (
          long_variable_name_1,
          long_variable_name_2,
          long_variable_name_3
      )
    • vertical_hanging_indent:

      from my_module import (
          long_variable_name_1,
          long_variable_name_2,
          long_variable_name_3
      )

    你可以使用--multi-line参数来指定多行import语句的风格:

    isort --multi-line grid your_code.py
  • 包含future imports: 默认情况下,isort会将__future__ imports放在最前面。你可以使用--future-first参数来修改这个行为:

    isort --future-first your_code.py
  • 跳过import排序: 你可以使用# isort:skip注释来跳过对某一行import语句的排序。例如:

    import os
    import sys  # isort:skip
  • 自定义import分组: 你可以使用--sections参数来自定义import分组。例如:

    isort --sections STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER your_code.py

    这个例子定义了四个import分组:STDLIB(标准库)、THIRDPARTY(第三方库)、FIRSTPARTY(本地库)和LOCALFOLDER(本地文件夹)。

你也可以创建一个pyproject.toml文件或者.isort.cfg文件来配置isort。例如:

[tool.isort]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
use_parentheses = true
line_length = 88

把这个文件放在项目的根目录下,isort会自动读取这些配置。

4. isort示例

假设我们有如下代码:

import os
import sys
from my_package import my_module
import requests
from . import utils

使用isort格式化后,代码会变成这样:

import os
import sys

import requests

from my_package import my_module
from . import utils

可以看到,isort自动将import语句按照标准库、第三方库、本地库的顺序进行了分组,并且按照字母顺序排列。

再看一个例子:

from my_module import (
    long_variable_name_1,
    long_variable_name_3,
    long_variable_name_2,
)

使用isort格式化后,代码会变成这样:

from my_module import (
    long_variable_name_1,
    long_variable_name_2,
    long_variable_name_3,
)

isort会自动按照字母顺序排列import的变量名。

第三部分:black + isort = 完美CP

blackisort就像一对天作之合的CP,它们可以一起工作,让你的代码更加完美。

1. 如何一起使用blackisort

最简单的方法就是先运行isort,再运行black

isort your_code.py
black your_code.py

但是,这种方法可能会有问题。因为black可能会修改isort的结果,导致代码不符合isort的规范。

一个更好的方法是使用--profile black参数:

isort --profile black your_code.py
black your_code.py

--profile black参数告诉isort按照black的风格进行格式化,这样可以避免black修改isort的结果。

你也可以使用pre-commit来自动运行blackisortpre-commit是一个用于管理git pre-commit hooks的工具。它可以让你在每次提交代码之前自动运行blackisort,确保你的代码符合规范。

2. 使用pre-commit配置blackisort

首先,安装pre-commit

pip install pre-commit

然后,在项目的根目录下创建一个.pre-commit-config.yaml文件,内容如下:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-added-large-files

  - repo: https://github.com/psf/black
    rev: 23.3.0
    hooks:
      - id: black

  - repo: https://github.com/pycqa/isort
    rev: 5.12.0
    hooks:
      - id: isort
        args: ["--profile", "black"]

这个文件定义了三个hook:

  • trailing-whitespace:删除行尾的空格。
  • end-of-file-fixer:确保文件以换行符结尾。
  • check-yaml:检查YAML文件的语法。
  • check-added-large-files: 检查添加的大文件
  • black:使用black格式化代码。
  • isort:使用isort格式化import语句,并按照black的风格进行格式化。

最后,运行pre-commit install命令来安装git hooks:

pre-commit install

现在,每次你提交代码时,pre-commit会自动运行这些hook,确保你的代码符合规范。如果hook运行失败,提交会被阻止,直到你修复代码为止。

第四部分:常见问题解答

Q:blackisort会影响我的代码逻辑吗?

A:不会。blackisort只会修改代码的格式,不会修改代码的逻辑。你可以放心地使用它们。

Q:blackisort的配置很复杂吗?

A:不复杂。black的配置选项不多,isort的配置选项虽然比较多,但是都有默认值,你可以根据自己的需要进行修改。

Q:我可以使用其他代码格式化工具吗?

A:当然可以。Python社区有很多优秀的代码格式化工具,例如autopep8yapf等。但是,black是目前最流行的代码格式化工具之一,它的优点是配置简单、效果好。

Q:pre-commit会影响我的开发效率吗?

A:不会。pre-commit只会在你提交代码时运行,不会影响你的日常开发。而且,它可以帮助你及早发现代码格式问题,避免在Code Review阶段浪费时间。

第五部分:总结

blackisort是Python开发者的利器,它们可以帮助我们统一代码风格、提高代码可读性、减少代码冲突。如果你还没有使用它们,赶快行动起来吧!让你的代码也拥有Tony老师级别的颜值!

希望今天的课程对大家有所帮助!下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注