题图:from instagram
在 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 3 会存在。为什么要破坏兼容性,改变 unicode/str/bytes,使得老代码移植到 python 3 非常困难。
最根本的原因是,在 python 2 中文本和二进制数据是一个烂摊子。比如 'abcd' 这个表达式,在 python 3 中,语义非常明确,就是包含四个字母的字符串,但是在 python 2 里,可以是四个字母的字符串,也可以代表 97、98、99、100 的数组。你可以使用print ord('a')获取到这个字母的 ascii。总之,在 python 2 中,对于 str 代表的含义有两种,这改变了语言的唯一性。而在 python 3 中答案是唯一的。
「python之禅」里讲过,「找到一种或唯一的一种解决方案去解决问题」。文字既能代表文本数据又能代表二进制数据这很麻烦。一旦对象脱离我们的控制,就会让人变得恐慌。有人说我们可以用 unicode,但实际中人们并不会那么做,有事还会引发不必要的麻烦。比如在 python 2 中,中文显示是这样的:
>>> geektime = “极客时间”
>>>geektime
'\xe6\x9e\x81\xe5\xae\xa2\xe6\x97\xb6\xe9\x9\xb4'
python 3 就简明很多:
'极客时间'
简化语言,移除 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 和 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 呢?
关于 instagram 和 python 的故事,大家可以下载「极客时间」,找到热点专题里的「编程语言」,一篇长文,有详细的描述。
python 相关文章:
人生苦短,我用 python
python 之禅
python 的进击
点击阅读原文,下载极客时间 ios 版。