引言:
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),持续发布《中国开源年度报告》,联合发起了“中国开源先锋榜”、“中国开源码力榜”等,在海内外产生了广泛的影响力。