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语言自身

  1. Python官方文档更喜欢采用单引号。(Python 3.6: 80% vs 20%)

  2. Python标准库更喜欢采用单引号。(Python 3.6:74% vs 26%)

  3. repr() 采用单引号。

二、现实世界

  1. 很多热门开源Python项目用单引号。(无数据支持)

  2. 有些公司要求使用单引号。(无数据支持)

  3. PEP 规范里的例子更多地使用单引号。(无数据支持)

  4. Guido(Python之父)更倾向于使用单引号。(无数据支持)

  5. 有些程序员用双引号表示供人类阅读的字符串,用单引号表示供机器阅读的字符串。

三、工具

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

四、易读性和易写性

  1. 使用某些字体时,单引号空字符串比双引号的空字符串更难辨认。

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

  3. 采用双引号就不必转义ASCII的单引号。

  4. 采用单引号就不必转义双引号。

  5. 大部分键盘布局都更容易打出单引号。(美国、中国、英国的键盘都更容易打出单引号,其他的键盘布局至少单引号和双引号需要同样次数的按键,不存在双引号更容易打的情况)

五、其他语言

  1. C语言使用双引号。

  2. 其他流行编程语言都用双引号。(如C#, Java, ...)

  3. 英语散文的引用使用双引号。

为什么说这位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.

相关推荐
起名字真南15 分钟前
【OJ题解】C++实现字符串大数相乘:无BigInteger库的字符串乘积解决方案
开发语言·c++·leetcode
tyler_download27 分钟前
golang 实现比特币内核:实现基于椭圆曲线的数字签名和验证
开发语言·数据库·golang
小小小~27 分钟前
qt5将程序打包并使用
开发语言·qt
hlsd#28 分钟前
go mod 依赖管理
开发语言·后端·golang
哇咔咔哇咔28 分钟前
【科普】conda、virtualenv, venv分别是什么?它们之间有什么区别?
python·conda·virtualenv
小春学渗透29 分钟前
Day107:代码审计-PHP模型开发篇&MVC层&RCE执行&文件对比法&1day分析&0day验证
开发语言·安全·web安全·php·mvc
杜杜的man32 分钟前
【go从零单排】迭代器(Iterators)
开发语言·算法·golang
亦世凡华、32 分钟前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang
测试界的酸菜鱼1 小时前
C# NUnit 框架:高效使用指南
开发语言·c#·log4j
GDAL1 小时前
lua入门教程 :模块和包
开发语言·junit·lua