从Python 2 到Python 3 实践篇(一)

本文对比了Python2与Python3的主要区别,包括除法运算商类型的变化、dict_keys和dict_values类的引入、range类的使用以及print语句的变更等。并建议开发者考虑过渡到Python3。

    目前Python的主要发展分两个分支,即Python 2 Python 3Python 2始于20016月的Python 2.0.1的发布,历经17年的发展,共发布了8个大的版本。20135月发布的Python 2.7.5是一个相当稳定且受欢迎的版本,Python 2.7发布后,虽然,至今仍然有小的新版本发布,如:20179月发布的Python2.7.14, 但是,Python官方决定不再发布针对Python 2大的新的版本。Python 3始于200812月的Python 3.0.0的发布,历经9年,共发布了7个大的版本,不断更新,时至今日,Python 3.6.4201712月发布。Python 3的一个缺点是,所拥有支持的库相对Python 2少,所以用惯了Python 2的用户对此可能相当不习惯,但是这一状况目前已经得到很大的改善。关于Python 2Python 3的发展,Python官方的立场是:Python 2.x is legacy, Python 3.x is the present and future of the language
    笔者认为Python3最大优势是:Python3的默认编码规则是utf-8,这相对于Python2ascii,在处理各种语言和文本字符方面功能强大了许多倍。在使用Python2处理含有非ascii码的文档时,会遇到UnicdoeDecodeError
    了解Python 2Python 3的优缺点,我们想是不是可以在一台电脑上同时装Python2Python3呢?这样我想用哪个版本就用哪个版本。停!停!停!这绝对是个危险的操作,在一台装有Python 2.7.5的电脑(Windows 64位操作系统)中,安装Python 3.4 (或者3.53.6)后,原Python 2.7.5IDLE GUI无法打开。即使卸载Python 3后,还是无法打开Python 2.7.5IDLE GUI。这是一个典型的不兼容问题。所以,我们需要根据我们的工作在Python 2Python 3中做出一个选择。

笔者最近将一个在Python 2.7.5上运行得很顺利的源代码,放到Python 3.4.4上运行,

出现一些错误,一一总结分析,以飨读者。

1. 除法运算中商的默认类型的改变。

Python 2中,如果被除数和除数都是整数,那么商默认类型是整数(int),即使商是小数,输出也是取整后的值。如果要想获得小数,那么除数或者被除数之一需要写出浮点数的形式。

Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information.

>>> 7/2

3

>>> 7/2.0

3.5

>>> 7.0/2

3.5

Python 3中,除法运算中商的默认类型的改变了,即无论被除数和除数的形式,商的默认类型是浮点数(float)。这一点回归到人们日常生活的方式。

Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information.

>>> 7/2

3.5

>>> 4/2

2.0

上述改变在一些具体应用场合会引起错误,在Python3.4中:

>>> Num = 7/2

>>> [3]*Num

Traceback (most recent call last):

  File "<pyshell#3>", line 1, in <module>

    [3]*Num

TypeError: can't multiply sequence by non-int of type 'float'

2. dict_keys,dict_values类的出现。

Python 2中,一个字典的所有键构成一个列表(List),所有的值构成一个列表(List)。

例如:给定一个关于水果和单价(元/斤)的fruit_dict字典。在Python 2.7.5中:

>>> fruit_dict

{'grape': 27.0, 'apple': 5.66, 'mango': 10.6, 'watermelon': 5.38, 'orange': 5.9, 'Cherry_Chili': 45.8}

>>> fruit_dict.keys()

['grape', 'apple', 'mango', 'watermelon', 'orange', 'Cherry_Chili']

>>> type(fruit_dict.keys())

<type 'list'>

Python 3中,一个字典的所有键构成一个字典键类(dict_keys),所有的值构成一个字典值类(dict_values)。在Python 3.4.4中:

>>> fruit_dict.keys()

dict_keys(['grape', 'apple', 'mango', 'watermelon', 'orange', 'Cherry_Chili'])

>>> type(fruit_dict.keys())

<class 'dict_keys'>

Python 3.4中运行如下程序:

>>> for fruit in fruit_dict.keys():

if fruit_dict[fruit] > 10:

del fruit_dict[fruit]

Traceback (most recent call last):

  File "<pyshell#15>", line 1, in <module>

    for fruit in fruit_dict.keys():

RuntimeError: dictionary changed size during iteration

如何解决这个问题呢?只需将dict_keys转化成列表即可。

>>> for fruit in list(fruit_dict.keys()):

if fruit_dict[fruit] > 10:

del fruit_dict[fruit]

3. range类的出现,取消xrange类型。

Python 2中,一个range()函数能直接生成一个列表类型(List type)。例如:

>>> range(10)

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

为了在生成大的列表时,避免占用大的内存空间,Python 2中有一个xrange()函数,输出是xrange类型。

>>> x = xrange(100000)

>>> x

xrange(100000)

>>> type(x)

<type 'xrange'>

 

Python3中,一个range()函数生成的是一个range类(range class)。由此,取消了Python 2中的xrange()函数。

>>> x = range(10)

>>> x

range(0,10)

>>> type(x)

<class range>

 

List类型有:.append(), .count(),.extend(),.index(),.insert(),.pop(),.remove(),.reverse(),.sort() 9种操作;range类有:.count(),.index(),.start,.stop,.step5种操作。两种仅有2种操作可以共用,所以,在Python 3中,

>>> x

Range(0,10)

>>> x.reverse()

Traceback (most recent call last):

  File <pyshell#43>, line 1, in <module>

x.reverse()

AttributeError: range object has no attribute reverse

解决方法,将range class转化成 list再做处理。

4. Print 变成了函数print()。此处比较简单,不再举例说明。

小结:

基于个人应用经验和Python的官方立场,笔者个人认为应该过渡到Python 3上来,即使我们可能对Python2已经非常熟悉。从Python 2Python3,如果是小段的源代码,可以通过自己一步一步的解决,对于大量的源代码,可以通过2to3这个工具来处理大部分内容,如果有特殊需要将Python3的源代码转换成Python2的代码,可以使用3to2这个工具。后面再分享这方面的使用情况。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值