Python 3.0 之破旧立新

  • Ze'ev Bubis
  • 李明(nasi)

2009 年 3 月 28 日

话题:编程语言Python架构语言 & 开发

Python 3.0(又名 Python 3000)在三个月之前终于发布(2008 年 12 月 3 日)。自 Python 之父 Guido van Rossum 开始展望这个全新的、革命性的 Python 版本,已经过去了近 9 年光景。Python 3.0 打破了与旧有版本的向后兼容性。

在 2007 年的一篇博文中,Guido 写到了Python 3.0 的构思

一直以来,除非要打破向后兼容性,否则很多缺陷和错误都无法修复。因此,Python 3000 将会作为第一个放弃向后兼容性的 Python 版本,目的就是要让 Python 向着最好的语言前进。

在稍后的一次访问中,Guido 叙述了接下来的事情

大约在三年之后,我开始切实地投入进来,开始真正的设计它,时间大约就在我加入 Google 之后,对于 Python 我有了更多的时间。很长一段时间里,项目推进的很快,很多人因此而激动。我每年都在包括 PyCon 和 Euro Python 等很多会议上做演讲。在过去的 12 个月里,在开发者社区搞定了全部的细节并已经准备好发布了以后,虽然不是全部的投入,但是我花了很大一部分精力在上面,坐下来好好享受这个过程。

尽管 Python 3.0 打破了对 Python 2.x 的向后兼容性,但是其发布和 Python 2.6 的发布一道,为开发者提供了一种便捷和安全的方式,来实验各种新的特性。和之前的 Python 版本一样,Python 2.6 保持了对之前版本的全兼容,而且还包含了Python 3.0 的新玩意(一些新特性需要通过“from __future__ import”来启用)。

Python 3.0 的新特性

Guido 说 Python 3.0 最出色的特性便是,“对 Unicode 的更好的支持,对各种'垃圾'进行清理”。而其中对 unicode 的全面支持则是变革的一个主要方面。Guido写到

所有的文本都是 Unicode;然而,编码过的 Unicode 的会以二进制的数据来表示…… 基于这个哲学来修改的结果是,只使用 Unicode 的代码清爽了许多,编码和二进制数据都需要为此做出修改。这个修改是正面的,因为在 2.x 的世界里,大量的 bug 都是因为以编码的文本和未编码的文本混杂在一起而产生的。

尽管 Python 2.x 也支持 Unicode,但是它是通过一个(旧有的)str 类型和一个(新的)unicode 类型来实现的。在 Python 3.0 之中,所有的字符串都是 unicode 的(str 就是 unicode 字符串),并引入了一个叫做 bytes 的新类型来处理字节序列。

Python 3.0 的其他修改包括:

  • Print 是一个函数 ─ print 语句已经被一个print()函数所替代。通过关键字参数来替代旧有 print 语句绝大多数的特殊语法(可以在 Python 2.6 中通过 from __future__ import print_function 来进行试验)。更多请参阅PEP 3105 ─ 让 print 变为函数
  • 用迭代器来替代列表 ─ 一些知名的 API 将不再返回列表。而字典的 dict.iterkeys()、dict.itervalues() 和 dict.iteritems() 方法将会移除,而你可以使用.keys()、.values() 和.items(),它们会返回更轻量级的、类似于集合的容器对象,而不是返回一个列表来复制键值。这样做的优点是,可以直接在键和条目上进行集合操作,而不需要再复制一次。
  • 整型数 ─ 移除了含糊的除法符号('/'),而只返回浮点数。在以前的版本中,如果参数是 int 或者是 long 的话,就会返回相除后结果的向下取整(floor), 而如果参数是 float 或者是 complex 的话,那么就会返回相除后结果的一个恰当的近似。在 2.6 版本中可以通过 from __future__ import division 来启用这项特性。更多请参阅PEP 238 ─ 修改除法操作符
  • 大量的语法修改

目前已经做了大量的工作,来使得向 3.0 版本的迁移尽可能的简单。很多新特性被反向移植到了 2.6 版本中,而且有一个新的命令行开关,可以打开对即将在 Python 3.0 中移除的特性的警告。你可以使用该开关来运行代码,来看看要将代码移植到 3.0 需要做多少工作。另外,有一个新工具叫做“2to3”,可以阅读 Python 2.x 的源代码,并执行一系列的修补器,来将代码转换为 Python 3.x 的代码。Guido 还补充到

事实上,2to3 工具有一种模式,是可以不直接修改代码的,而默认情况下它是会的。你可以让它输出标准的 diff 来看看修改了什 么。如果需要的话,你可以逐个文件的去审校,然后再决定是否做出修改。“哦,没错,它这么做是对的。” 或者经过仔细审校以后,发现实际上这个工具犯了错误。你可以手工地修复这个文件,来重新进行修补。这样的话,工具依然会帮你节省大量的工作。这在 Python 2.6 到 3.0 的转换中是有先例的。

是应该选择 Python 2.6 还是 3.0 来进行开发?Guido这样说到

… 决定选 3.0 抑或 2.6 是一个比较个人的选择。此时此刻,你不会为作为一个保守者而承担任何风险。2.6 依然会和 3.0 一样,会受到核心 Python 开发者的良好支持。同时,我们也不会稍稍降低 3.0 的质量和重要性。因此,如果你并没有外部需求,比如说依赖某个包或者第三方软件,而它们还没有被移植到 3.0,或者你并不是在一个大家都用 2.x 的环境中的话,那么就没有必要裹足不前了。

Python 及其社区最被人称道之处,就在于其做到了保守地前行,每个版本之间都做到了良好的向后兼容性。现在,Python 社区要做些与众不同的事──通过牺牲向后兼容性来开发一个更好的语言版本。Java 社区也一直有这样的想法,但是自从 1.2 版本(又名 Java 2)之后,“糟糕和丑陋之处”便不敢再去修正,怕的便是会破坏现有的代码。

查看英文原文:Python 3.0 Breaks with the Past

编程语言Python架构语言 & 开发