洪尔莫斯 开源社KAIYUANSHE

引言:

Black Formatter 是 Python Software Foundation 主导的开源项目,它最初面世时强制规定了 Python 字符串必须用双引号。这就引发了广大用户在 github 的激烈讨论和吐槽,其中不乏枚举各种开源项目中字符串使用单引号的例子。Black 的第一作者面对诸多用户的“口诛笔伐”坚持自己的原则,从强硬拒绝到激烈讨论再到最终妥协,中间经历许多大佬们的讨论与劝解。

Python 字符串应该用双引号还是单引号?这是一个值得思考的问题。一方面,作为语言模型,应当拥有一个规范而统一的标准,便于管理。另一方面,Python 毕竟是面向公众的,必须结合简便程度和用户使用分布进行抉择。对此,我们希望能听到大家的声音,请在留言区留下您的想法吧。

PyCharm 升级至2023.2版本后,经常弹出来一个提示问我要不要试一下 Black formatter。

试了一下,这个 Black formatter 很有个性,特别喜欢换行。我的一个文件用 PyCharm 自带的代码整理器整理完之后是500行左右,然后再用 Black 整理就变成600多行了。

原来 Black 是 Python Software Foundation 主导的开源项目,Python 亲儿子,口号也很有个性:The uncompromising Python code formatter。

它的 Uncompromising 还体现在它 github 上的第118个 issue,2018年提出,是一个讨论了上百楼的神贴。

他们讨论的问题是:字符串应该用双引号还是单引号。

Python 的字符串既允许双引号也允许单引号,甚至允许三引号。这种灵活性自然引起群魔乱舞,特别是双引号和单引号,大家基本上有自己的喜好。然而 Black 毫不妥协,规定只能用双引号。

提问者 bofm 手上维护着一些更喜欢用单引号的旧项目,他问能不能提供一个选项让用户保留单引号。

他列出了一些理由:

  • 存量项目已经采用单引号规则。
  • Python 官方文档例子都用单引号。
  • repr() 返回单引号。
  • 很多著名项目都用单引号
  • PEP 的例子大多数用单引号。
  • Guido(Python之父)在他最新的 github commits 里使用单引号。

事实上,作者还未出来,另外一个用户就已经点灭这个 issue,他说 Black 的优点就是消灭掉这些鸡毛蒜皮的选择。接着 Black 的第一作者出来了。这位第一作者 Lukasz Langa 是大神,Python 核心团队成员,波兰人,钢琴家。

他(github 账号是 ambv)认为 bofm 说的理由都不是理由,就相当于说“由于其他项目无原则,所以 Black 也不应该有原则”。这种盲从权威(an appeal to authority)的做人态度是不行的,Black 是 uncompromising 的,绝不妥协。况且存量项目仍然可以用,只是可能看不惯格式化后的代码。

这时有个人出来帮 bofm 说话,他说技术上很容易满足 bofm 的需求,black 已经提供了每行字数的选项,再加一个选项很容易,如果官方不肯加,那就 Fork 一个分支自己干。

这最后一句话可能激怒了 ambv,他说虽然 MIT 协议允许你们随便 fork 单干,但在我的帖子里提到 fork 我会感到被冒犯,希望以后不要再提。

ambv 说作为一个标准化格式化工具,太多的选择对用户来说反而是一个负担,也会使用户进一步要求更多选择(正如上面那个人提到的,既然提供每行字数的选项,为什么不能再加一个选项)。

ambv 强调一定要标准化,反而不怎么关心究竟是双引号还是单引号更好,反正选其中一个就行。在决定使用哪个引号之前,他曾经和 carljm 和 zsol 商议,他们说服了他双引号更好,所以最终用双引号。

ambv 还反驳了在键盘上更容易敲打单引号的论据,他认为你喜欢打单引号就只管打,反正最后 Black 一键帮你转成双引号,毫不费力。

说完,ambv 就暂时关闭了这个 issue,说如果有更充分的理由,他会重新打开。这时距离这个帖子的诞生只过了3天。

尽管 issue 暂时被关闭,但各路人马仍然蜂拥而至表达自己的观点。其中有一位叫 alanhamlett 的仁兄语气比较冲。

前面提到 ambv 说他咨询过 carljm 和 zsol 的意见才选择了双引号,alanhamlett 上来就直接 @zsol 问他为什么双引号比单引号更好。ambv 见到有人在自己的地盘绕开他,分明是不把他放在眼内,于是反问 alanhamlett:README 里的解释还不够吗?

岂料 alanhamlett 直接开大。他说:对,那个解释就是不够。你应该遵循 Prettier's example 允许用户选择用哪个引号,而不是把大量开发团队拒之门外。他还补充到,这个话题太鸡毛蒜皮(bikeshedding)了,作者接受群众意见允许选择就完事了,婆婆妈妈干什么(婆婆妈妈是我加上去的)。

ambv 当然要马上还击。他提醒 alanhamlett 注意言辞,就算你的观点是对的,但你说话的方式仍然很难让别人接受。下面是他的教训环节:

仅仅因为你不同意另一方的观点,就说一个话题幼稚,这只会令事态升级。指责我把“大量开发团队拒之门外”是夸张和不公平的。指导我们这些用爱发电的开源项目作者“该做什么”是很傲慢的。你是局外人,没资格要求任何东西。

ambv 总结了他的观点:Black 是 PEP 8 规范的子集,定义很清晰。Black 永远不会提供“使用单引号代替双引号”的选项,因为这违背了 Black 的标准化原则,一旦开了允许选择的先例就无法收拾。他考虑的是是否允许“不强制单引号转成双引号”(即 bofm 一开始的诉求:保留单引号)。他表示对此话题保持开放态度,但担心以后越来越多豁免这豁免那的要求。这和 Black 的强迫症原则有冲突。

这时有个叫 audiolion 的人火上加油。他说他曾经很欣赏 black 这个项目,但强制单转双这点不能忍,如果 black 不改变的话,他永远不会使用 black,也不会向宣传 black。他认为没有任何论据能够令 ambv 回心转意,但还是劝告 ambv 提供选择,这样会使大家都满意。

如果你不改,我保证有人会 fork 一个版本帮你改掉,其他功能都保持一致。这不是要篡夺你的王座,只是为与你观点不同的人提供一个选择。

很奇怪,这次 ambv 没有回喷,只是默默地重新打开了这个 issue。这时距离帖子诞生日差不多两个月。

 这时候有个叫 zestyping 的重量级人物出来了。他在 Hacker News 那边就参加过这个议题,现在跟到这边吃瓜。他说希望贡献自己的一份力量(更重要的原因是周六晚上没事干),就把帖子里的各方观点整理一遍,尽量中立地展示各种论据。他还很贴心地按照“来源”和“类别”两个大方向组织论据。这里按类别展示:

一、Python 语言自身

  • Python 官方文档更喜欢采用单引号。(Python 3.6:80% vs 20%)
  • Python 标准库更喜欢采用单引号。(Python 3.6:74% vs 26%)
  • repr() 采用单引号。

二、现实世界

  • 很多热门开源 Python 项目用单引号。(无数据支持)
  • 有些公司要求使用单引号。(无数据支持)
  • PEP 规范里的例子更多地使用单引号。(无数据支持)
  • Guido(Python之父)更倾向于使用单引号。(无数据支持)
  • 有些程序员用双引号表示供人类阅读的字符串,用单引号表示供机器阅读的字符串。

三、工具

  • 在 Sublime Text 里,使用双引号会导致一些高亮颜色失效。

四、易读性和易写性

  • 使用某些字体时,单引号空字符串比双引号的空字符串更难辨认。
  • 双引号造成更大的视觉干扰。
  • 采用双引号就不必转义 ASCII 的单引号。
  • 采用单引号就不必转义双引号。
  • 大部分键盘布局都更容易打出单引号。(美国、中国、英国的键盘都更容易打出单引号,其他的键盘布局至少单引号和双引号需要同样次数的按键,不存在双引号更容易打的情况)

五、其他语言

  • C 语言使用双引号。
  • 其他流行编程语言都用双引号。(如C#, Java, ...)
  • 英语散文的引用使用双引号。

为什么说这位 zestyping 是重量级人物?

因为他刚整理完各方观点,ambv 就来 say hi。

原来 zestyping 之前也为 Python 贡献过代码,ambv 的 black 实际上还使用了 zestyping 贡献的 lib2to3,所以 ambv 感谢了 zestyping 的贡献。

感谢归感谢,ambv 还是逐条指出论据的瑕疵 Python 官方文档更“喜欢”地采用单引号。Python 标准库更多“喜欢”采用单引号。

ambv 认为这两个论据不对。单引号是使用得更多,但官方并没有推荐任何一种引号。ambv 很肯定大部分作者都不关心使用哪种引号。

Guido 更倾向于使用单引号。

ambv 说他跟 Guido 谈过心,这条也不对。Guido 说他喜欢把双引号用在给人读的文本,把单引号用在数据上。

在 Sublime Text 里,使用双引号会导致一些高亮颜色失效。

ambv 说"This make me sad"。这明明是一个 bug,应该去修复它,怎么会成为支持单引号的论据?

双引号造成更大的视觉干扰。

ambv 怀疑这是不是由于一些字体设计得过于糟糕。“什么是衡量视觉干扰的单位?两种引号之间的视觉干扰数值差异有多少?就算我们能回答上述无聊的问题,我也肯定差异很少,就像 M 比 N 的干扰更大、逗号比句号的干扰更大一样无聊。”ambv 连珠炮般地抨击。

zestyping 见到 ambv 的抗议后,改成:

  • Python 官方文档更“多”地采用单引号。
  • Python 标准库更多“多”地采用单引号。
  • Guido 更“多”地使用单引号。

打动 ambv 的似乎是一个叫 kadrach 的用户做的统计。他统计了下载量最多的前100名 python 库里单引号占比的分布图,如下图所示:

ambv 很感兴趣,当然他也马上指出这个统计不完善,因为这里包含了备注和其他字符串里的引号。他要求用 AST(不知什么意思,大概是语法树?),统计前1000名的库,并且重复的文件只统计一次。

ambv 和 kadrach 就这个统计的实现方法讨论了很久,在这过程中 ambv 的立场似乎逐步软化(虽然我没看到有什么统计成果)。

这时一个叫 kbd 的用户做结案陈词:纵观整个帖子,最重要的论据是很多人(包括 Python 之父)都使用不同的引号来表示不同的意思,双引号表示“人类可读的文本”,单引号表示“数据”。kbd 说检查了自己的代码,发现自己下意识地也遵循了这种规范,所以这种潜意识可能是普遍现象。

ambv 马上表示同意,他认为这也是最有说服力的论据。这一天是2018年5月30日。

在几个人附议之后,ambv 在5月31日发布了18.6b0版本,终于提供了 --skip-string-normalization 选项。

这个 issue 是4月9日提出的,4月12日被关闭,5月27日重开,5月31日解决。

ambv 看上去固执,实际上还是很关注大家的意见,并且很讲道理的。

I hope this resolves to your satisfaction what's been the most controversial issue in Black's history.

转载自丨Python 猫

编辑丨王军

相关阅读 | Related Reading

开源软件的真实价值(哈佛商学院研究报告-初稿.微信导读)

开源亚洲行,和开源社一起出发 FOSSASIA SUMMIT!

COSCUP 2024 正式启动议题征集,开源社专属邀请通道开启,欢迎报名参加!

开源社简介

开源社(英文名称为“KAIYUANSHE”)成立于 2014 年,是由志愿贡献于开源事业的个人志愿者,依 “贡献、共识、共治” 原则所组成的开源社区。开源社始终维持 “厂商中立、公益、非营利” 的理念,以 “立足中国、贡献全球,推动开源成为新时代的生活方式” 为愿景,以 “开源治理、国际接轨、社区发展、项目孵化” 为使命,旨在共创健康可持续发展的开源生态体系。

开源社积极与支持开源的社区、高校、企业以及政府相关单位紧密合作,同时也是全球开源协议认证组织 - OSI 在中国的首个成员。

自2016年起连续举办中国开源年会(COSCon),持续发布《中国开源年度报告》,联合发起了“中国开源先锋榜”、“中国开源码力榜”等,在海内外产生了广泛的影响力。


开源社
6 声望1 粉丝

开源社成立于 2014 年,是由志愿贡献于开源事业的个人成员,依 “贡献、共识、共治” 原则所组成,始终维持厂商中立、公益、非营利的特点,是最早以 “开源治理、国际接轨、社区发展、开源项目” 为使命的开源社区联...