目前,Python的主要发行版本分为Python 2.x分支和Python 3.x分支。为了不增加负担,Python 3在设计时没有考虑向下兼容。许多用早期Python版本编写的程序都无法在Python 3上正常执行。为了兼容这些程序,诞生了过渡版本Python 2.6,它基本使用了Python 2.x的语法和库,同时考虑了向Python 3的迁移,允许使用部分Python 3的语法与函数。Python官方建议新的程序使用Py-thon 3的语法,除非运行环境无法安装Python 3或者程序本身使用了不支持Python 3的第三方库。而即使无法立即使用Python 3,也建议编写兼容Python 3版本的程序,然后使用Python 2.6、Python 2.7来执行。
与Python 2.x分支相比,Python 3.x分支的变化主要有以下几个方面。
Python 2.x分支中的str()是ASCII编码方式,而unicode()不是byte类型,这导致中文等语言在直接输出显示时并不方便阅读,示例如下。
而Python 3.x分支直接默认使用UTF-8编码,支持源文件中使用Unicode字符串,上述例子在Python 3.x分支中的运行结果如下。
以下代码也是合法并可以正常运行的。
相比Python 2.x分支,Python 3.x分支在数据类型上的主要变化有以下几点。
(1)去除了long类型,只有一种整型int,但它的行为就像Python 2.x分支中的long。
(2)统一了非十进制字面量的表示方法。
在Python 2.x中,八进制数可以写成0o777或0777;而在Python 3.x中,八进制数只能写成0o777,写成0777将会报错。同时,Python 3.x中新增了二进制字面量和bin()函数,用于将一个整数转换成二进制字符串。
(3)新增了bytes类型,对应Python 2.x的八位串,示例如下。
str对象和bytes对象可以使用encode()(将str转为bytes)和decode()(将bytes转为str)方法相互转化,示例如下。
dict的.keys()、.items和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有dict.has_key(),该方法可以用in替代。
字符串只有str一种类型,与Python 2.x分支的unicode几乎一样。
相比Python 2.x分支,Python 3.x分支在语法上的主要变化有以下几点。
(1)去除了<>,全部改用!=表示不相等。
(2)去除了",全部改用repr()函数。
(3)关键词加入了as和with,以及True、False、None。
(4)整型除法改为返回浮点数,要得到整型结果可使用//。
(5)加入了nonlocal语句,可以使用noclocal x直接指派外围(非全局)变量。
(6)去除了print语句,加入了print()函数实现相同的功能;去除了exec语句,改为exec()函数。
(7)改变了顺序操作符的行为。例如,x<y,当x和y类型不匹配时则抛出TypeError,而不是返回随机的bool值。
(8)使用input函数代替raw_input函数作为读取键盘输入的方式。
(9)去除了元组参数解包,不能使用def(a,(b, c)):pass的方式定义函数。
(10)扩展了可迭代解包。在Python 3.x中,只要rest是list对象且seq是可迭代的,以下语句就是合法的。
(11)定义了新的super()方法,可以不再给super()方法传参数。
(12)启用了新的metaclass语法,示例如下。
(13)支持类装饰器,用法与函数装饰器一样,示例如下。
相比Python 2.x分支,Python 3.x分支在面向对象的程序设计上的主要变化有以下几点。
(1)引入了抽象基类Abstraact Base Classes。
(2)容器类和迭代器类被抽象基类化,所以Python 3.x分支的Collections模块里的类型比Python 2.x分支多了很多,示例如下。
(3)迭代器的next()方法改名为__next__(),并增加了内置函数next(),用以调用迭代器的__next__()方法。
(4)增加了@abstractmethod和@abstractproperty两个装饰器,因此编写抽象方法或抽象属性时更加方便了。
相比Python 2.x分支,Python 3.x分支在异常处理上的主要变化有以下几点。
(1)所有异常都从BaseException继承,删除了StardardError。
(2)去除了异常类的序列行为和.message属性。
(3)用raise Exception(args)代替raise Exception,args语法。
(4)捕获异常的语法改变,引入as关键字来标识异常实例,示例如下。
相比Python 2.x分支,Python 3.x分支在模块上的主要变化有以下几点。
(1)移除了cPickle模块,用pickle模块代替。
(2)移除了imageop、audiodev、Bastion、bsddb185、exceptions、linuxaudiodev、md5、Mime Writer、mimify、popen2、rexec、sets、sha、stringold、strop、sunaudiodev、timing、xmllib、bsddb、new模块。
(3)os.tmpnam()函数和os.tmpfile()函数被移动到了tmpfile模块下。
(4)tokenize模块使用bytes工作,它的主要入口点不再是generate_tokens,而是tokenize.to-kenize()。
Python 3.x分支还在以下方面进行了改进和调整。
(1)xrange()改名为range(),要想使用range()获得一个list,必须显式调用。
(2)bytes对象不能hash,也不支持b.lower()、b.strip()和b.split()方法,但可以使用以下两种代码代替后两者,以达到相同的目的。
(3)zip()、map()和filter()都返回迭代器,去除了apply()、callable()、coerce()、execfile()、reduce()和reload()等函数。使用hasattr()来替换callable().hasattr()的语法,示例如下。
(4)string.letters和相关的.lowercase、.uppercase被去除,改用string.ascii_letters。
(5)__getslice__系列成员被废弃。a[i:j]根据上下文转换为a.__getitem__(slice(I,j))或__set-item__和__delitem__。
(6)file类被废弃。例如,在Python 2.x中:
而在Python 3.x分支中:
本书如未明确提示所用Python版本,一般都是指Python 3.x分支的最新版。