为什么存在 Python 3
这个月,我在 PuPPy (普吉特海湾 Python 用户组) 举行了一个 Q&A ,这最终使得我解释了为什么 Python 3 应运而生,以及整个字符串/字节的处理过程。最终,我收到了一个对于这个解释的赞赏,这让我有点吃惊,因为我天真的以为人们都知道为什么创造 Python 3。
事后看来,假设大多数的人们,不管是 Python 的新手还是熟手,都已经被告知或由好奇心驱使去追寻发现关于这个问题的解释,是非常愚蠢的。因此,这篇博客目的在于简单的解释为什么 Python 3 存在,特别是为什么我们选择了完全向后兼容的 unicode
/ str
/ bytes
修改,因为这是向 Python 3 移植代码真正棘手的部分。
Python 2 中的文本和二进制数据一团糟
快速看一下,下列文字语义上表示了什么?
'abcd'
如果你是 Python 3 用户,你可能会说,这是由字母"a", "b", "c"和"d"按顺序组成的字符串。
如果你是 Python 2 用户,你可能会说同样的话。你也有可能会说它代表了 97, 98, 99, 和 100 字节。这就是事实。在 Python 2 中有关于 str
对象代表了什么的两种正确的解释,这就导致了修改语言,从而使得单独的 Python 3 答案是唯一的答案。
Python 之禅 说,“应该有一个 -- 最好是只有一个 -- 明显的方法来做到”。让语言中的文字可以代表文本数据或者二进制数据是一个问题。例如,如果你从网上读到一些东西,那你则必须非常小心辨别所返回的 str
对象代表的是二进制数据还是文本数据,因为一旦这个对象离开了你的掌控,那么你就不可能知道了。或者在你的代码中,你打算将 str
对象转换成文本数据 -- 或者其他什么的 -- 但你搞砸了,并且不小心跳过了那一步,此时可能会出现一个错误。由于 str
对象可能代表了两个不同语义的类型,因此很难注意到这类型的上滑(slip-up) 会在何时发生。
现在,你可能尝试并且辩解道,如果避免为文本数据使用 str
类型,而是用 unicode
取而代之,这些问题都可以 Python 2 中去解决。虽然这是完全正确的,但是实际上人们不会这样做。要么是人们想偷懒,所以不想劳神解码为 Unicode,因为这需要额外的工作;要么人们对性能要求极高,并尽量避免解码的成本。
无论是哪种,都假设你会好好编码以避免把事情搞得一团糟,然而,我们都知道,我们实际上是不完美的人类,都有可能犯错。若人们对于使用 Python 2 写出没有 bug 的代码的希望能够成真的话,那么我就不会不断的从基本每个将他们的代码移植到 Python 3 的人那儿听到,他们在他们的代码中发现了关于编码解码文本和二进制数据的潜在错误。
避免错误这一点是人们忘记的一个大问题。语言的简化和移除一个 str 对象可能代表的潜在含义会使得代码倾向于具备更少的错误。Python 之禅指出,“显式胜于隐式”,是有原因的:歧义和隐性知识不是易于沟通的代码,它们容易出错,导致错误。通过迫使开发者明确地分离他们的二进制数据和文本数据,会导致某一类错误发生机率更低的更好的代码。
世界上的其他地方都在使用 Unicode (有很好的理由)
人们有时候会忘记,Python 有多老了;Guido 在 1989 年 12 月开始编写 Python,在 1991 年 2 月作为开源代码第一次发布。这意味着 Python 自身早于 1991 年 10 月发布的 Unicode 标准第一卷 。在几年间,Unicode 标准化后创建的语言选择基于能够支持 Unicode 的编码来实现字符串。这使得 Python 2 位于这种不幸的位置,在这种情况下,它在 2004 年(Python 3 计划开始的时候) 获得了重要的关注,但由于 unicode
类型完全是可选的,并且人们不是对所有的文本数据使用此类型,它可以说是提供了对 Unicode 文本最薄弱的支持。
从任何一种书面语言支持 Unicode 和文本是很重要的。Python 是世界的语言,而不仅仅是那些支持 ASCII 覆盖的罗马字母的语言。这就是为什么当涉及到文本时,Python 3 使它成为"Unicode 或者 bust";它保证了所有的 Python 3 代码将支持世界上的所有人,无论开发者是否明确的编写代码指出。在 Python 2 中,那些花时间正确的为文本数据指定 unicode 类型的项目和不这么做的项目之间已经出现了分裂;而在 Python 3 中,并不存在这样的分裂,并且免费的支持所有的语言。
我们假设 Python 会越来越受欢迎
2004 年,我们开始 PEP 3100 ,从而开始设计 Python 3 (旁白: PEP 最初的编号是 3000,但是我们重新将它编号为 3100,这样 编号为 3000 的 PEP 将是关于我们如何处理 Python 3 开发的 PEP)。我们知道,Python 的人气呈上升趋势,我们希望它的增长可以继续(令人欣慰的是,确实是这样的☺)。但是,这也意味着,如果我们要解决任何设计错误,以及帮助语言继续普及,我们需要现在来做,而不是等到以后。我们假设,如果我们没有把 Python 3 弄糟,一旦 Python 2 只用于旧版项目,而不是新版,Python 3 将会比 Python 2 持续更长的时间和被使用更多,那么在一个足够长的时间段内会有更多的 Python 3 代码而不是 Python 2。因此,我们决定忍受 Python 2/3 的转型之痛,并在这个假设下创造 Python 3。很显然,这需要几十年才能看到,在这个世界上,就代码行数而言,Python 3 的代码是否超过了 Python 2。
我们将不会再做此类型的向后兼容改动了
我们团队已经决定,不会再突然做像 unicode
/ str
/ bytes
这样大的变动了。在我们开始 Python 3 的时候,我们认为(希望)社区会跟随 Python 所做的,完成最后一个支持 Python 2 特性的发布,然后切到 Python 3 进行特性开发,而只 Python 2 版本的修正版本。这显然并未发生,而我们也吸取了教训。另外,我们并未看到这门语言的基本设计中有任何缺点以致于需要做如此大的变动。所以,希望 Python 4 不会做任何比可能从标准库中移除过时模块更强烈的动作了。
总结
这就是为什么会是这样的。我们意识到,由于在 Python 2 中过度的使用 str
类型,人们一直有一堆的问题,所以在 Python 3 中,我们通过明确地将文本数据从二进制数据中分隔开来来解决它们。另外,让所有的文本数据自动的支持 Unicode,有助于项目更容易与多种语言一起工作。而当我们这样做的时候还,我们进行了更改,因为我们觉得越快越好。我们构造了过渡,认为社区将跟随我们留下 Python 2,但是事实并非如此,取而代之的,我们已经花费了更多的时间,并使用一个 Python 2/3 兼容子集来管理过渡。
原文: Why Python 3 exists (Or, the whole unicode/str/bytes thing was done for a reason)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 在 Python 3 中比较类型
下一篇: 数据库知识点分享
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论