我为什么不喜欢 black

栏目: Python · 发布时间: 4年前

内容简介:Black是一个代码格式化工具,项目上个月刚迁移到Python组织下,意味着这是一个社区认可的项目。项目诞生不久我就点了Star,到现在已经1w+ star了,但是我一直没写文章推荐过它,因为我并不完全认可它。了解我的人都知道我是非常愿意接受和尝试新鲜事物的,凡是有益于社区的发展我都会支持。好像到现在,除了类型注解我不喜欢以外,其他的我都觉得Ok,包含非常有争议的海象运算符(PEP 572)。今天闲来无事给大家聊聊这件事,本文不是纯技术文章,更多的是我的个人观点,请按需阅读。

前言

Black是一个代码格式化工具,项目上个月刚迁移到 Python 组织下,意味着这是一个社区认可的项目。项目诞生不久我就点了Star,到现在已经1w+ star了,但是我一直没写文章推荐过它,因为我并不完全认可它。

了解我的人都知道我是非常愿意接受和尝试新鲜事物的,凡是有益于社区的发展我都会支持。好像到现在,除了类型注解我不喜欢以外,其他的我都觉得Ok,包含非常有争议的海象运算符(PEP 572)。

今天闲来无事给大家聊聊这件事,本文不是纯技术文章,更多的是我的个人观点,请按需阅读。

为什么不喜欢

作者给black的定义是「The Uncompromising Code Formatter」,也就是「不妥协的代码格式化程序」。什么意思呢,一句话: 你要听它的,由black按照它的审美帮助你处理代码格式问题。black的格式化规则是PEP8的超集,也就是除了处理成符合PEP8规范要求的代码,也有black的一些规则。

说到这里让我想到了Golang的gofmt工具: Golang的开发团队制定了统一的官方代码风格,使用官方的gofmt帮助开发者格式化他们的代码到统一的风格。虽然这样降低了自由度,但是极大的节省了开发者对于代码风格的纠结,争论等等,现在写 Go 代码时我会在编辑器配置保存时自动格式化,我非常喜欢这么用。

当你对Python语言语法和PEP 8非常熟悉,手写的代码基本符合PEP8的要求,那么这个时候你对代码格式化的感受应该和我一样。我现在如果写完代码运行flake8有1-2个错误(我写Python代码不配置autopep8等工具),我会视错误类型考虑直接用autopep8这样的 工具 直接解决问题: 因为没必要手改,看错误就知道什么问题了。这个时候就要充分利用代码格式化工具的效率了。

所以我不是不喜欢代码格式化,而是非常喜欢。所以不喜欢的原因是 black里面的规则 。如果你用过black,使用 black --help 可以发现它的参数非常少,几乎没有配置参数,这更印证了 不妥协 :按我的来就可以了。

我举2个规则例子。

单引号 or 双引号

默认black要求你必须用双引号把字符串包起来,而不是单引号。如果你看过我写的代码,会发现我99%用单引号,如果没有必要我是从来不会用双引号的。其实在black早期版本(18.6b0 之前),是没有-S参数(--skip-string-normalization)选择要不要把字符串标准化。作者非常坚持的认为首选应该是双引号,但事实上非常多开发者都是用单引号的,或者单双不敏感的,所以有一些开发者提了个Issue(延伸阅读链接1),这个讨论很长,有很多开发者参与,有兴趣的可以看看。从结果来看,虽然加了选项(目前唯一个可由选项值决定格式化效果的),作者是不情愿的妥协了,但是通过整个对话中可以看到作者对于自己观点的固执和...,想了一会不知道用什么词,就说 洁癖 吧。对于这一点我是非常理解的,聪明的、有天赋的人大多具备这样的特质:不妥协,而且这属于开发者自己的风格,Owner可以决定项目的一切。

在写这篇文章时,我翻了下最近几个月核心开发者对CPython提交的代码,大部分都是用单引号,另外有些开发者(如vstinner,ncoghlan,asvetlov,benjaminp等)对单引号双引号不敏感,混用。其实Black作者ambv给CPython提交的代码中也是混用的。所以 推荐标准化字符串引号用双引号 这个规则我不能理解和接受。我接受并且会改正一切现在被认为是正确的用法,哪怕过去是反模式(Anti-pattern)的。我举个PEP8 W503/W504的例子:

# Line break occurred before a binary operator (W503)

## 反模式:point_down:
income = (gross_wages
          + taxable_interest)

## 最佳实践
income = (gross_wages +
          taxable_interest)

过去我写的代码是:point_up_2:这种最佳实践风格的:运算符放在上一行结尾。但是后来加了W504错误:

# Line break occurred after a binary operator (W504)
## 反模式:point_down:
income = (gross_wages +
          taxable_interest)

## 最佳实践
income = (gross_wages
          + taxable_interest)

是不是有点懵,这2 种错误是不是很让人抓狂?无论你写成那种风格都会抛另外一种风格错误,非常有趣。而且过去的最佳实践成为了反模式,过去的反模式成了最佳实践!

我学PEP8 很早,由于这个PEP改动频率极低,很久我都没看了。结果16年让我重学一次PEP 8。但是这种学习和接纳是必要的。

说回来这件事,按我的做人做事风格,我会接纳使用它的开发者的意见,一个人提的观点我可能不重视,但是如果有多人都提出意见那么我肯定会说服他们(至少要说服大部分),或者对这部分做出妥协。

import的多行输出模式

在大型项目里面一个模块中从其他模块导入的内容是非常多的,black对import的处理是按照isort Multi line output Mode 3 + trailing comma实现的(isort支持的模式很多,可以看延伸阅读链接4了解)。假如有这么一句:

from sansa.models.consts import (
    BLACKLIST_GROUP_ID, BANNED_GROUP_IDS, TAG_REC_POOL,
    STORY_TAG_HOME_REC_BANNED, HOME_REC_BANNED_TAG_NAME)

black会直接格式化成:

from sansa.models.consts import (
    BLACKLIST_GROUP_ID,
    BANNED_GROUP_IDS,
    TAG_REC_POOL,
    STORY_TAG_HOME_REC_BANNED,
    HOME_REC_BANNED_TAG_NAME,
)

这部分可以看Issue 127(延伸阅读5)。对我来说,我有2个意见:

  1. 格式化后 HOME_REC_BANNED_TAG_NAME 行尾添加了逗号,我觉得这个逗号多余。我日常开发中都是按需添加逗号,不会多加。
  2. black强制限制了开发者import的格式化方案。我日常写代码,用的是 Multi line output Mode 6 ,也就是 Hanging Grid Grouped, No Trailing Comma 。配置和效果类似这样:
❯ cat .isort.cfg
[settings]
line_length=79
multi_line_output=6
include_trailing_comma=False
force_grid_wrap=0
use_parentheses=True
❯ isort test.py
❯ cat test.py
from sansa.models.consts import (
    BANNED_GROUP_IDS, BLACKLIST_GROUP_ID, HOME_REC_BANNED_TAG_NAME,
    STORY_TAG_HOME_REC_BANNED, TAG_REC_POOL
)

也就是说本来我的代码写的风格没问题,但是经过black格式化之后,还要用isort再过一遍。black给我选的Mode 3(Vertical Hanging Indent)我不喜欢。如果你了解知名的Python开源项目,你会发现Mode 6风格的有很多:Django、Sentry、Requests、Pipenv、IPython、DRF、Pip、mypy。而Mode 6的只翻到了Mode 3。emmm...

PS:其他模式的我没有列出来,另外对于模式3和模式6我没有完整确认,可能有些项目混用了多种模式,这毕竟是开发者相关的。

综上所述,我觉得没必要限制 多行import 的格式化效果。

不喜欢和不用

Black 作者是非常知名的 Python 核心开发,无论技术能力和社区贡献我都不可企及,我写这篇文章算是妄议。

有一点,不喜欢不等于不用,我过去已经在厂内一个Top 3大型项目中应用了black,主要是处理一些遗留代码的格式化问题。

那我的性格,如果某一天black成为flake8这样的Python开发标配,我会选择Fork一个版本,去掉那些我不认可的规则,应用到个人和团队的项目中~

延伸阅读


以上所述就是小编给大家介绍的《我为什么不喜欢 black》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTML5

HTML5

Matthew David / Focal Press / 2010-07-29 / USD 39.95

Implement the powerful new multimedia and interactive capabilities offered by HTML5, including style control tools, illustration tools, video, audio, and rich media solutions. Understand how HTML5 is ......一起来看看 《HTML5》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具