在 Python 3 出现之前,Python 在我眼里一直都是一位稳重扎实的大叔,资历深厚,语法简单,功能强大,兼顾面向对象和函数式编程,库包丰富程度也让其他语言转过来的程序员瞠目结舌并喟叹:人生苦短,要用 Python 啊……这种情况一直持续到 Python 3 的出现。

一种语言版本的升级是极为普通且常见的事情,不升级才算的上不正常,但是Python 3 算的上是一个例外,因为 Python 3 放弃了向下兼容,也就是说,你在 Python 2 系列版本中写的代码,一直好好的运行着,只要放到 3 的环境里,就有 99% 的可能性不能正常运行了。最简单的,你在 Python 2 中打印语句print “Hello World”,放到 Python 3 里,系统会告诉你「SyntaxError: Missing parentheses in call to ‘print’」。刺激不刺激?

Python 的开发者这么做是为什么呢,或者说Python 3为什么会出现呢?在很长的一段时间之内,没有人出来解释这件事,Python 的创造者们认为,这不是很显然易见的嘛。这就好比一个有着超高幽默感的人就算是听到了一个冷笑话也能乐得前仰后合哈哈大笑,另一个人 —— 比如普通开发者 —— 却把一颗冰凉的花生米放嘴里边嚼边问,哥们,你特么到底在笑啥呢?

Python 3为什么会存在呢?Brett Cannon —— Python 的核心开发者 —— 在一次问答活动中终于给出了一个合理的解释。在此之前他一直神奇的认为大家都清楚知道 Python 3 为什么会出现。他说:

回想起来我真是太傻了,竟然会认为大部分人 —— 不管是刚接触 Python 或者已经学过Python有一段时间 —— 要么应该知道,要么就会充满好奇心去获取一个解释或答案。然而并没有。所以我来解释一下 Python 3 为什么会存在。兼容性为什么要被破坏,改变 unicode/str/bytes,使得老代码移植到 Python 3 非常困难。

最根本的原因是,中文本和二进制数据在 Python 2 中是一个烂摊子。比如在 Python 3 中, ‘abcd’ 这个表达式,语义非常明确,就是包含了四个字母的字符串,但是四个字母的字符串,在 Python 2 里,也可以代表 97、98、99、100 的数组。你可以使用 print ord(‘a’) 获取到这个字母的 ASCII。总之,对于 str 代表的含义,在 Python 2 中就有两种,这改变了语言的唯一性。而在 Python 3 中答案是唯一的。

「Python之禅」就有讲过,「找到一种或着唯一的一种解决方案就是去解决问题」。文字既能代表文本数据又能代表二进制数据这样就会很麻烦。一旦对象脱离我们的控制,就会让人变得恐慌。有人说我们可以用 Unicode,但是实际中的人们并不会那样去做,有时还会引起不必要的麻烦。比如中文显示,在 Python 2 中是这样的:

>>> geektime = “极客时间”>>> geektime’\xe6\x9e\x81\xe5\xae\xa2\xe6\x97\xb6\xe9\x9\xb4’

Python 3 就简明很多:

>>> geektime = “极客时间”>>> geektime’极客时间’

简化语言,移除 str 的二义性就能够减少代码的出错率。避免出 bug 是一件很重要的事情,但却常常被人遗忘。Python 之禅中的另一句话「清晰胜于晦涩」也是表达了这个意思,歧义和隐性知识使得代码不容易沟通,并容易形成 bug。
正如 Brett Cannon 所言,人们有时会忘记 Python 有多久的历史了

1989年的冬天,Guido 开始编写 Python 语言的编译器和解释器,为了度过一个有意义的圣诞节。1991年2月,第一个 Python 版本诞生,编译器是用 C 语言实现的。这意味着自从Python的出现早于 1991年10月发布的第一版 Unicode 标准后。后面再出现的语言,比如 Java,Ruby 等都选择在支持 Unicode 的标准上实现自己的 str 类型,这就让 Python 3 变得比较尴尬。2004年 Python 3 的方案开始酝酿,这时开发者们才意识到,支持 Unicode 和来自任何语言的的文本是非常重要的。

Python 是一门面向世界的语言,而不仅仅是那些支持 ASCII 码覆盖的罗马数字的语言。这就是 Python 3 在处理文本时要选择使用 Unicode 的原因。

Python 3 的开发过程大致是这样的:

在 2004 年我们开始设计 Python 3。我们清楚知道 Python 的受欢迎程度在不断上升,我们也希望能够延续这种势头。但同时这也意味着如果我们想要及时修正所有的设计缺陷来保证它的受欢迎度,趁现在最好而不是以后。我们设想 Python 3 相较于 Python 2 会有持续更长的一段时间,而不是 Python 2.7 只是用来维护以前遗留的项目,新项目中重不会用到,那用 Python 3 写出的代码一定会比用 Python 2 的更多。所以我们才决定来承受由 Python 2 向 3 转型之痛,换来更好的。并且在这种设想下开发了 Python 3。

以后这种打破向后兼容性的事情我们再也不会做了。

然而事情显然没有开发者想象的那么简单,由于向下的兼容性的缺乏,并且 Python 2 中的代码历史悠久,库包丰富,而且大部分程序都是生产环境的应用,迁移成本太高,没有那么多显而易见的好处。另外,由于 Python 2 是如此好用以至于开发者们掌握了熟练的技巧从而避免 str 带来的陷阱。发布完 Python 3 之后,Python 的核心开发者们都认为社区会最终摒弃上一个版本,痛痛快快的向着新世界转向。但事与愿违,两个版本并存的情况持续了近十年之久。导致Python 的开发者们又要花费更多的时间设计了一个对 Python 2/3 的兼容子集来实现这种过渡。

那么该学 Python 2 还是 Python 3 呢?如果要是五年前我会推荐学习 Python 2,两年前我推荐都要学都要掌握,事实上在 Mac 环境里用 homebrew 安装和使用两个版本的环境是非常方便的。时至今日,大量的库已经开始普遍支持 Python 3 了,而且 Python 3 的特性已经远远不是解决 str 问题了,所以我现在会推荐你直接学习 Python 3。

看看 Instagram 的案例,在相当长的一段时间,Instagram 都跑在 Python 2.7 + Django 1.3 的组合之上。经过一系列的讨论之后,他们最终做出一个重大的决定:升级到 Python 3。

Python 3 有什么优势呢?新特性,比如如何类型注解 Type Annotations;提供了更好的性能;并且社区的支持重心已经完全迁移到 Python 3,还有什么理由再去使用 Python 2 呢?

更多推荐

Python 3和Python如何去选择?老司机来带带你吧!