您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > Python2.x和3.x主要差异总结
Python2.x和3.x主要差异总结开始使用Python之后就到处宣扬Python如何如何好,宣传工作的一大重要诀窍就是做对比,比如原先用Java的时候做个什么东西要写多少代码,怎么个别扭,现在用Python实现同样的功能怎么个简单等等。不过谈Python,不管怎么谈,老会谈到Python2.x和3.x的版本差异问题,这个差异真不是一般的大,从一个简单的print到核心库的改进都牵扯到了很多,现在总结了一些主要的差异点。基本类型(1)整形在python2.x中,有两种整数类型,一般的32位整数和长整数,长整数都是以L或者l(不建议使用小写l,容易跟1搞混),超过32位长度之后会自动转换为长整形。在python3.x中,允许我们更随心所欲更自然的使用整数,只有一种类型,没有长度限制。python2.x?1210000000000000000000000000000000001000000000000000000000000000000000Lpython3.x?1210000000000000000000000000000001000000000000000000000000000000(2)八进制字面量表示在Python2.x中,表示八进制字面量有两种方式,一是同众多我们所熟悉的编程语言一样,直接在数字前加0,比如01000,另外是加0o(0和小写字母o)0o1000在Python3.x中,表示八进制字面量的方式只有一种,就是0o1000python2.x?12340o100051201000512python3.x?123456701000Filestdin,line101000^SyntaxError:invalidtoken0o1000512运算符(1)不等于测试Python2.x中不等于有两种写法!=和Python3.x中去掉了,只有!=一种写法,还好,我从来没有使用的习惯(2)去掉了repr表达式``Python2.x中反引号``相当于repr函数的作用Python3.x中去掉了``这种写法,只允许使用repr函数,这样做的目的是为了使代码看上去更清晰么?不过我感觉用repr的机会很少,一般只在debug的时候才用,多数时候还是用str函数来用字符串描述对象。(3)除法运算Python中的除法较其它语言显得非常高端,有套很复杂的规则。Python中的除法有两个运算符,/和//首先来说/除法:在python2.x中/除法就跟我们熟悉的大多数语言,比如Java啊C啊差不多,整数相除的结果是一个整数,把小数部分完全忽略掉,浮点数除法会保留小数点的部分得到一个浮点数的结果。在python3.x中/除法不再这么做了,对于整数之间的相除,结果也会是浮点数。Python2.x:?12341/201.0/2.00.5Python3.x:?121/20.5而对于//除法,这种除法叫做floor除法,会对除法的结果自动进行一个floor操作,在python2.x和python3.x中是一致的。python2.x:?12-1//2-1python3.x:?12-1//2-1注意的是并不是舍弃小数部分,而是执行floor操作,如果要截取小数部分,那么需要使用math模块的trunc函数python3.x:?12345importmathmath.trunc(1/2)0math.trunc(-1/2)0(4)比较运算符Python2.x中允许不同类型的对象进行比较,比如:?1234-1''True1''FalsePython3.x中则不允许这类不同类型之间含糊不清的比较:?12341''Traceback(mostrecentcalllast):Filestdin,line1,inmoduleTypeError:unorderabletypes:int()str()我觉着即使在2.x中也不应该使用这种含糊不清的比较,1''返回了False,这个是基于什么判断的?说不清楚。语句(1)print这是应该算是最广为人知的一个差别了吧,Python2.x和Python3.x之间连HelloWorld都是不兼容的。python2.x中print是语句?1printfilex,y向打开的输出流file中输出x,y变量的值在python3.x中这句要这么写?1print(x,y,file=file)file参数定义的默认值是sys.stdout(2)扩展序列解包python中的序列赋值一直是这门语言宣传时候的一个亮点,能把一个序列解开进行赋值:?123456789101112131415x,y=[1,2]x1y2x,y=1,2x1y2x,y=y,xx2y1python3.x对这一功能更加进行了强化,支持扩展序列解包:?1234x,*y=1,2,3x1y5[2,3]内置集合类型内置集合的差别主要体现在字典对象的几个视图方法上,keys\items和values,在2.x中这几个试图方法每次都是赤裸裸的返回一个新的列表,3.x对这种粗鲁的行为做了优化,返回的是迭代器对象。另外原先字典对象有个has_key方法来判断key在字典中是否存在,这个方法实现的功能跟in运算符完全一样,因此在3.x就把这个方法给干掉了。函数(1)nonlocal作用域在2.x的时代,Python只有两个作用域,模块里面的全局作用域和函数的局部作用域,但是随着在函数中定义函数的情况越来越多,比如装饰器、闭包等等,这里面就出现了内层函数引用外层函数变量的问题:比如我要在内层函数修改外层函数的一个变量,在Python2.x的时代就会出现错误:?1234567891011defout_function():...call_count=0...defin_function():...call_count+=1...returnin_function...out_function()()Traceback(mostrecentcalllast):Filestdin,line1,inmoduleFilestdin,line4,inin_functionUnboundLocalError:localvariable'call_count'referencedbeforeassignment但是在Python3.x中只要使用nonlocal关键字对变量进行修饰,就会自动去外层函数寻找变量:?1234567defout_function():...call_count=0...defin_function():...nonlocalcall_count...call_count+=1...returnin_function...8out_function()()(2)Key-wordonly参数前面我们说到print在Python3.x中是作为函数提供的。print的参数设计是这样的:?1print(*value,sep='',end='\n',file=sys.stdout)如果了解Python参数的顺序规则,我们知道在Python2.x中,参数的顺序必须遵循以下规则去定义:deffunction(一般参数or带默认值参数,*sequence,**dict)而这个地方却允许先定义*sequence再去定义一般参数,这就是Python3.x所支持的key-wordonly的参数形式。在一个*之后允许去定义一些参数,这些参数在函数调用的时候必须指定参数名称。这样本质上其实就是在*sequence类型的参数之后固定写死了一个**dict,当然也可以在后面继续定义一个**dict:?1deftest(*value,name,**dict):但这样写就不对了deftest(*value,**dict,name)(3)map、filter和reduce这三个函数号称是函数式编程的代表。在Python3.x和Python2.x中也有了很大的差异。首先我们先简单的在Python2.x的交互下输入map和filter,看到它们两者的类型是built-infunction:?1234mapbuilt-infunctionmapfilterbuilt-infunctionfilter它们输出的结果类型都是列表:?1234map(lambdax:x*2,[1,2,3])[2,4,6]filter(lambdax:x%2==0,range(10))[0,2,4,6,8]但是在Python3.x中它们却不是这个样子了:?12345678mapclass'map'map(print,[1,2,3])mapobjectat0xa6fd70cfilterclass'filter'filter(lambdax:x%2==0,range(10))filterobjectat0xa6eeeac首先它们从函数变成了类,其次,它们的返回结果也从当初的列表成了一个可迭代的对象,我们尝试用next函数来进行手工迭代:?123456789f=filter(lambdax:x%2==0,range(10))next(f)0next(f)2next(f)4next(f)6对于比较高端的reduce函数,它在Python3.x中已经不属于built-in了,被挪到functools模块当中。模块Python2.x和3.x模块之间的差别主要体现在相对导入这部分的规则上。在Python2.x和3.x当中都是使用点号来指定在当前包下进行相对导入,但是在没有点号的情况下,Python2.x会以先相对再绝对的模块搜索顺序,3.x的顺序跟这个相反,默认是绝对的,缺少点号的时候,导入忽略包含包自身并在sys.path搜索路径上进行查找。面向对象(1)经典类和新式类PythonOO最神奇的地方就是有两种类,经典类和新式类。新式类跟经典类的差别主要是以下几点:1.新式类对象可以直接通过__class__属性获取自身类型:type2.继承搜索的顺序发生了改变,经典类多继承属性搜索顺序:先深入继承树左侧,再返回,开始找右侧;新式类多继承属性搜索顺序:先水平搜索,然后再向上移动3.新式类增加了__slots__内置属性,可以把实例属性的种类锁定到__slots__规定的范围之中。4.新式类增加了__getattribute__方法Python2.x中默认都是经典类,只有显式继承了object才是新式类Python3.x中默认都是新式类,不必显式的继承objectpython2.x:?12345ClassicClass.__class__Traceback(mostrecentcalllast):Filestdin,line1,inmoduleAttributeError:classClassicClasshasnoattribute'__class__'classNewClass(object):6789...pass...NewClass.__class__type'type'python3.x:?1234classNewClass:pass...NewClass.__class__class'type'(2)无绑定方法在Python2.x中除了类方法和静态方法,其余的方法都必须在第一个参数传递self跟实例绑定,但是在Python3.x中废除了这条规定,允许方法不绑定实例,这样的方法跟普通的函数没有区别:Python2.x:?12345classMyClass:...deffunction():...printfunction...MyClass.funct
本文标题:Python2.x和3.x主要差异总结
链接地址:https://www.777doc.com/doc-4209735 .html