Python高级技术之:`Python`的`black`和`isort`:自动化代码格式化和导入排序。

咳咳,大家好,欢迎来到今天的“Python代码整容术”讲座。今天我们要聊的是blackisort这两位代码界的“Tony老师”,它们能让你的Python代码焕然一新,变得整洁美观、易于维护。

一、代码格式化:丑小鸭变白天鹅的魔法棒

想象一下,你写了一段代码,功能强大,逻辑清晰,但是…

def my_function( long_parameter_name , another_long_parameter_name):
    if (True):
        print("Hello, world!")
    else:
        return 123

是不是感觉有点… 难以言喻?缩进混乱、括号随意、空格任性,代码就像一个蓬头垢面的小丑,即使内心充满才华,也让人难以接近。

这就是代码格式化要解决的问题。它像一个魔法棒,能将杂乱无章的代码变成赏心悦目的艺术品。

black就是Python世界里最流行的代码格式化工具之一。它遵循一套严格的、约定俗成的代码风格,能够自动地将你的代码格式化成统一的、规范的样式。

1. black的安装和使用

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

pip install black

安装完成后,就可以使用black来格式化你的代码了。例如,要格式化一个名为my_module.py的文件,只需要执行:

black my_module.py

black会直接修改你的代码文件,并按照它的规则进行格式化。如果你不想直接修改文件,可以使用--check参数来检查代码是否符合black的规范:

black --check my_module.py

如果代码不符合规范,black会输出错误信息,告诉你哪里需要修改。

2. black的格式化规则

black有一套自己严格的格式化规则,例如:

  • 行长度限制: 默认情况下,black会将代码行长度限制在88个字符以内。
  • 字符串引号: 优先使用双引号,除非字符串中包含双引号,或者为了避免转义字符。
  • 缩进: 使用4个空格进行缩进。
  • 括号和空格: 会自动添加或删除括号和空格,以保持代码的一致性。
  • 尾逗号: 会在多行列表、元组和字典的最后一项后面添加尾逗号。

例如,black会将以下代码:

def my_function(long_parameter_name,another_long_parameter_name):
    if(True):
        print(  "Hello, world!")
    else:
        return 123

格式化成:

def my_function(
    long_parameter_name, another_long_parameter_name
):
    if True:
        print("Hello, world!")
    else:
        return 123

可以看到,black自动地添加了换行、空格,并删除了不必要的括号,使代码更加易读。

3. black的配置

black提供了一些配置选项,可以让你自定义它的行为。例如,你可以修改行长度限制:

black --line-length 120 my_module.py

或者,你可以使用pyproject.toml文件来配置black。在项目的根目录下创建一个pyproject.toml文件,并添加以下内容:

[tool.black]
line-length = 120
target-version = ['py37'] # 指定 Python 版本
include = '.pyi?$'    # 包含的文件
exclude = '''
/(
    .eggs         # exclude a few common directories in the
  | .git          # root of the project
  | .hg
  | .mypy_cache
  | .tox
  | .venv
  | _build
  | buck-out
  | dist
)/
'''

这样,black在格式化代码时,就会读取pyproject.toml文件中的配置。

4. black的优点

  • 自动化: black可以自动地格式化代码,无需手动调整。
  • 一致性: black遵循一套统一的代码风格,可以保证代码库的一致性。
  • 易于使用: black安装和使用都非常简单。
  • 可配置: black提供了一些配置选项,可以让你自定义它的行为。

二、导入排序:代码的“收纳整理师”

想象一下,你的Python模块中有很多import语句,它们像一堆乱七八糟的衣服,堆在你的衣柜里:

import os
from django.shortcuts import render
import sys
from collections import defaultdict
import re
import logging
from typing import List, Dict

是不是感觉有点头疼?查找某个模块时,需要花费大量的时间。

isort就是来解决这个问题的。它像一个收纳整理师,能将你的import语句按照一定的规则进行排序,使代码更加整洁有序。

1. isort的安装和使用

安装isort同样简单:

pip install isort

安装完成后,就可以使用isort来排序你的import语句了。例如,要排序一个名为my_module.py的文件,只需要执行:

isort my_module.py

isort也会直接修改你的代码文件,并按照它的规则进行排序。同样,如果你不想直接修改文件,可以使用--check参数来检查代码是否符合isort的规范:

isort --check my_module.py

2. isort的排序规则

isort默认的排序规则如下:

  • 内置模块: 例如ossys等。
  • 第三方模块: 例如djangorequests等。
  • 本地模块: 你自己编写的模块。

在每个类别中,import语句按照字母顺序排序。from语句的排序方式与import语句类似,但是会先按照模块名排序,然后再按照导入的名称排序。

例如,isort会将以下代码:

import os
from django.shortcuts import render
import sys
from collections import defaultdict
import re
import logging
from typing import List, Dict
from . import models

格式化成:

import logging
import os
import re
import sys
from collections import defaultdict
from typing import Dict, List

from django.shortcuts import render

from . import models

可以看到,isort自动地将import语句按照类别和字母顺序进行了排序,使代码更加易读。

3. isort的配置

isort也提供了一些配置选项,可以让你自定义它的行为。例如,你可以修改排序规则、添加忽略模块等。

同样,你可以使用pyproject.toml文件来配置isort。在项目的根目录下创建一个pyproject.toml文件,并添加以下内容:

[tool.isort]
profile = "black"  # 使用 black 风格
multi_line_output = 3 # 多行输出,使用括号包裹
include_trailing_comma = true # 包含尾逗号
force_grid_wrap = 0 # 不强制网格环绕
use_parentheses = true # 使用括号
line_length = 88    # 行长度
skip = [".tox", ".venv"]  # 忽略的目录
known_first_party = ["your_project_name"] # 将你的项目名视为 first-party

这样,isort在排序import语句时,就会读取pyproject.toml文件中的配置。

4. isort的优点

  • 自动化: isort可以自动地排序import语句,无需手动调整。
  • 一致性: isort遵循一套统一的排序规则,可以保证代码库的一致性。
  • 易于使用: isort安装和使用都非常简单。
  • 可配置: isort提供了一些配置选项,可以让你自定义它的行为。
  • black兼容: isort可以与black完美配合,保证代码的整体风格一致。

三、blackisort的配合使用:打造完美代码

blackisort是天生一对,它们可以完美地配合使用,共同打造出整洁、美观、易于维护的Python代码。

1. 安装blackisort

首先,你需要安装blackisort

pip install black isort

2. 配置blackisort

建议使用pyproject.toml文件来配置blackisort。例如:

[tool.black]
line-length = 88
target-version = ['py37']

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

这里,我们指定了isort使用black的风格,并保持行长度一致。

3. 运行blackisort

你可以使用以下命令来同时运行blackisort

black . && isort .

或者,你可以使用pre-commit hooks,在提交代码之前自动运行blackisort

4. 使用 pre-commit hooks

pre-commit hooks 是一种在提交代码之前自动运行脚本的机制。它可以帮助你检查代码风格、运行测试等。

首先,你需要安装pre-commit

pip install pre-commit

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

repos:
  - repo: https://github.com/psf/black
    rev: 23.10  # 使用最新版本
    hooks:
      - id: black
  - repo: https://github.com/PyCQA/isort
    rev: 5.12.0 # 使用最新版本
    hooks:
      - id: isort
        args: ["--profile", "black"]

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

pre-commit install

现在,每次提交代码时,pre-commit 都会自动运行blackisort,并检查代码是否符合规范。如果不符合规范,pre-commit 会阻止你提交代码,直到你修复了代码风格问题。

四、进阶技巧

  • 忽略部分代码: 有时候,你可能希望blackisort忽略某些代码块。你可以使用# fmt: off# fmt: on来禁用black的格式化:

    # fmt: off
    very_long_variable_name = (
        "This is a very long string that "
        "should not be broken into multiple lines"
    )
    # fmt: on

    同样,你可以使用# isort: skip来跳过isort的排序:

    import os  # isort: skip
  • 集成到编辑器: 大多数流行的代码编辑器都支持blackisort的集成。你可以配置编辑器,使其在保存文件时自动运行blackisort

  • 持续集成:blackisort集成到持续集成(CI)流程中,可以确保代码库的代码风格始终保持一致。

五、常见问题解答

  • black会改变我的代码逻辑吗?

    不会。black只会改变代码的格式,不会改变代码的逻辑。

  • isort会改变我的代码行为吗?

    通常不会。isort只会改变import语句的顺序,不会改变代码的行为。但是,如果你的代码依赖于import语句的顺序,那么isort可能会导致问题。

  • 我应该使用black还是autopep8

    black是更现代、更流行的代码格式化工具。它遵循一套严格的代码风格,可以保证代码库的一致性。autopep8则更加灵活,可以自定义更多的格式化规则。如果你追求一致性,那么black是更好的选择。

  • 我应该如何处理blackisort的冲突?

    blackisort的冲突通常发生在行长度限制上。black默认的行长度限制是88个字符,而isort默认的行长度限制是79个字符。为了避免冲突,建议将isort的行长度限制设置为与black相同。

六、总结

blackisort是Python开发者的利器,它们可以帮助你自动化代码格式化和import语句排序,使你的代码更加整洁、美观、易于维护。掌握它们的使用,能够极大地提高你的开发效率,并保证代码库的质量。

希望今天的讲座能帮助你更好地理解和使用blackisort。 记住,好的代码风格不仅能让你的代码更容易阅读,也能让你在团队合作中更加高效。所以,大胆地使用blackisort,让你的代码焕发新生吧!

今天的“Python代码整容术”就到这里,谢谢大家! 祝大家编码愉快,早日成为代码界的“颜值担当”!

发表回复

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