在用写前端代码时,有一个必备的代码格式化插件 Prettier。它格式化出来的代码即美观,又能保持风格一致。同时配置项较少,在团队协作中,只要少量的配置,就能保证团队有统一的代码风格,使用起来不折腾。

    对 Python ,我们代码格式化比较常用的工具有 autopep8yapf ,但是这两个工具在格式化 Python 代码时多少都存在一些问题,格式化出来的代码风格并不统一,虽然可以通过配置项做一定的限制,但是比较繁琐。对大多数长代码的处理,好像就是让代码折行使其不超过列宽限制,这样格式化出来的代码并不美观。

    那么,Python 中有没有像 Prettier 那样好用的格式化工具呢?答案是 - Black!它是一个比较新的工具,看 Github 记录,第一版发布于 2018 年 3 月 15 日。同 Prettier 介绍有点类似,官方说法是:

    Black is the uncompromising Python code formatter。

    下面我们看 Black 是怎样的不妥协(uncompromising):

    在换行处理上,Black 尝试每行渲染一个完整表达式或简单语句。 如果这符合定义的列宽限制,那刚好:

    1. # in:
    2. l = [1,
    3. 2,
    4. 3,
    5. ]
    6. # out:
    7. l = [1, 2, 3]

    如果没有,Black 将查看第一个外部匹配括号的内容,并将其放在单独的缩进行中:

    1. # in:
    2. ImportantClass.important_method(exc, limit, lookup_lines, capture_locals, extra_argument)
    3. # out:
    4. ImportantClass.important_method(
    5. exc, limit, lookup_lines, capture_locals, extra_argument
    6. )

    如果仍然不适合,它将使用相同的规则进一步分解内部表达式,每次都缩进匹配括号。 如果匹配括号对的内容以逗号分隔(如参数列表、字典等),则 Black 将首先尝试将它们与匹配括号保持在同一行。 如果这不起作用,它将把所有这些都放在不同的行中:

    1. # in:
    2. def very_important_function(template: str, *variables, file: os.PathLike, engine: str, header: bool = True, debug: bool = False):
    3. """Applies `variables` to the `template` and writes to `file`."""
    4. with open(file, 'w') as f:
    5. ...
    6. # out:
    7. def very_important_function(
    8. template: str,
    9. *variables,
    10. file: os.PathLike,
    11. engine: str,
    12. header: bool = True,
    13. debug: bool = False,
    14. ):
    15. """Applies `variables` to the `template` and writes to `file`."""
    16. with open(file, "w") as f:
    17. ...

    您可能已经注意到,右括号并没有进行缩进,并且始终添加尾逗号。 这种格式化会产生较小的差异;在添加或删除元素时,只需要改变一行即可。 此外,不对右括号进行缩进处理,在代码的两个不同部分之间提供了明确的分隔符,否则它们共享相同的缩进级别(如上面示例中的参数列表和 docstring)。

    一些流行的API,如ORM,会使用链式调用。 这种 API 风格被称为 流式接口。 Black 通过处理跟随调用或索引操作的 . 来格式化。看下面的例子:

    1. def example(session):
    2. result = (
    3. session.query(models.Customer.id)
    4. .filter(
    5. models.Customer.account_id == account_id,
    6. models.Customer.email == email_address,
    7. )
    8. .order_by(models.Customer.id.asc())
    9. .all()
    10. )

    非常清晰美观!

    那么我们在 Python 编辑器中怎么启用 Black 工具呢?下面介绍两种比较常用的 Python 编辑器的 VScode 和 Pycharm 的配置方法。
    首先都需要安装 Black:

    1. pip install black

    VScode 的配置相对比较简单,首先安装 Python 扩展(大多应该都已经安装),在配置项中搜索 black 找到相关配置项,修改即可:
    image.png
    对 PyCharm 配置相对复杂(有一个 Black 插件,但是不好用):
    首先在 Settings > Tools > External Tools 中添加配置项:
    image.png
    其中 Program 参数为 black 安装路径,如使用的是 Anaconda 则可能为:

    1. <%HOMEPATH%>\Anaconda3\Scripts\black.exe

    或者将 black 安装在项目虚拟环境中,用 Pycharm 提供的宏来配置:

    1. $PyInterpreterDirectory$\Scripts\black.exe

    然后定义一个快捷键,方便使用,我这边定义为 ctrl+alt+; ,紧邻默认的格式化快捷键 ctrl+alt+l

    image.png

    还可以定义 File Watchers ,这样在文件出现变动,特别是保存是能自动格式化代码:

    image.png
    快来 Black Playground 抢先体验吧!

    参考: