Python3和2经常使用语句的语法区别3.0

生成器的throw方法# 在Python 2里,生成器有一个throw()方法。调用a_generator.throw()会在生成器被暂停的时候抛出一个异常,而后返回由生成器函数获取的下一个值。在Python 3里,这种功能仍然可用,可是语法上有一点不一样。app

Notes Python 2 Python 3 ① a_generator.throw(MyException) no change ② a_generator.throw(MyException,'error message') a_generator.throw(MyException('error message')) ③ a_generator.throw('error message') unsupported 最简单的形式下,生成器抛出不带用户自定义错误信息的异常。这种状况下,从Python 2到Python 3语法上没有变化 。 若是生成器抛出一个带用户自定义错误信息的异常,你须要将这个错误信息字符串(error string)传递给异常类来以实例化它。 Python 2还支持抛出只有异常信息的异常。Python 3不支持这种语法,而且2to3会显示一个警告信息,告诉你须要手动地来修复这处代码。 全局函数xrange()# 在Python 2里,有两种方法来得到必定范围内的数字:range(),它返回一个列表,还有range(),它返回一个迭代器。在Python 3里,range()返回迭代器,xrange()再也不存在了。函数

Notes Python 2 Python 3 ① xrange(10) range(10) ② a_list = range(10) a_list = list(range(10)) ③ [i for iin xrange(10)] [i for iin range(10)] ④ for i in range(10): no change ⑤ sum(range(10)) no change 在最简单的状况下,2to3会简单地把xrange()转换为range()。 若是你的Python 2代码使用range(),2to3不知道你是否须要一个列表,或者是否一个迭代器也行。出于谨慎,2to3可能会报错,而后使用list()把range()的返回值强制转换为列表类型。 若是在列表解析里有xrange()函数,就没有必要将其返回值转换为一个列表,由于列表解析对迭代器一样有效。 相似的,for循环也能做用于迭代器,因此这里也没有改变任何东西。 函数sum()能做用于迭代器,因此2to3也没有在这里作出修改。就像返回值为视图(view)而再也不是列表的字典类方法同样,这一样适用于min(),max(),sum(),list(),tuple(),set(),sorted(),any(),all()。 全局函数raw_input()和input()# Python 2有两个全局函数,用来在命令行请求用户输入。第一个叫作input(),它等待用户输入一个Python表达式(而后返回结果)。第二个叫作raw_input(),用户输入什么它就返回什么。这让初学者很是困惑,而且这被普遍地看做是Python语言的一个“肉赘”(wart)。Python 3经过重命名raw_input()为input(),从而切掉了这个肉赘,因此如今的input()就像每一个人最初期待的那样工做。编码

Notes Python 2 Python 3 ① raw_input() input() ② raw_input('prompt') input('prompt') ③ input() eval(input()) 最简单的形式,raw_input()被替换成input()。 在Python 2里,raw_input()函数能够指定一个提示符做为参数。Python 3里保留了这个功能。 若是你真的想要请求用户输入一个Python表达式,计算结果,能够经过调用input()函数而后把返回值传递给eval()。 函数属性func_*# 在Python 2里,函数的里的代码能够访问到函数自己的特殊属性。在Python 3里,为了一致性,这些特殊属性被从新命名了。命令行

Notes Python 2 Python 3 ① a_function.func_name a_function.name ② a_function.func_doc a_function.doc ③ a_function.func_defaults a_function.defaults ④ a_function.func_dict a_function.dict ⑤ a_function.func_closure a_function.closure ⑥ a_function.func_globals a_function.globals ⑦ a_function.func_code a_function.code __name__属性(原func_name)包含了函数的名字。 __doc__属性(原funcdoc)包含了你在函数源代码里定义的文档字符串(docstring) __defaults__属性(原func_defaults)是一个保存参数默认值的元组。 __dict__属性(原func_dict)是一个支持任意函数属性的名字空间。 __closure__属性(原func_closure)是一个由cell对象组成的元组,它包含了函数对自由变量(free variable)的绑定。 __globals__属性(原func_globals)是一个对模块全局名字空间的引用,函数自己在这个名字空间里被定义。 __code__属性(原func_code)是一个代码对象,表示编译后的函数体。 I/O方法xreadlines()# 在Python 2里,文件对象有一个xreadlines()方法,它返回一个迭代器,一次读取文件的一行。这在for循环中尤为有用。事实上,后来的Python 2版本给文件对象自己添加了这样的功能。code

在Python 3里,xreadlines()方法再也不可用了。2to3能够解决简单的状况,可是一些边缘案例则须要人工介入。对象

Notes Python 2 Python 3 ① for line in a_file.xreadlines(): for line in a_file: ② for line in a_file.xreadlines(5): no change (broken) 若是你之前调用没有参数的xreadlines(),2to3会把它转换成文件对象自己。在Python 3里,这种转换后的代码能够完成前一样的工做:一次读取文件的一行,而后执行for循环的循环体。 若是你之前使用一个参数(每次读取的行数)调用xreadlines(),2to3不能为你完成从Python 2到Python 3的转换,你的代码会以这样的方式失败:AttributeError: '_io.TextIOWrapper' object has no attribute 'xreadlines'。你能够手工的把xreadlines()改为readlines()以使代码能在Python 3下工做。(readline()方法在Python 3里返回迭代器,因此它跟Python 2里的xreadlines()效率是不相上下的。) ☃继承

使用元组而非多个参数的lambda函数# 在Python 2里,你能够定义匿名lambda函数(anonymous lambda function),经过指定做为参数的元组的元素个数,使这个函数实际上可以接收多个参数。事实上,Python 2的解释器把这个元组“解开”(unpack)成命名参数(named arguments),而后你能够在lambda函数里引用它们(经过名字)。在Python 3里,你仍然能够传递一个元组做为lambda函数的参数,可是Python解释器不会把它解析成命名参数。你须要经过位置索引(positional index)来引用每一个参数。索引

Notes Python 2 Python 3 ① lambda (x,): x+ f(x) lambda x1: x1[0]+ f(x1[0]) ② lambda (x, y): x+ f(y) lambda x_y: x_y[0]+ f(x_y[1]) ③ lambda (x,(y, z)): x+ y + z lambda x_y_z: x_y_z[0]+ x_y_z[1][0]+ x_y_z[1][1] ④ lambda x, y, z: x+ y + z unchanged 若是你已经定义了一个lambda函数,它使用包含一个元素的元组做为参数,在Python 3里,它会被转换成一个包含到x1[0]的引用的lambda函数。x1是2to3脚本基于原来元组里的命名参数自动生成的。 使用含有两个元素的元组(x, y)做为参数的lambda函数被转换为x_y,它有两个位置参数,即x_y[0]和x_y[1]。 2to3脚本甚至能够处理使用嵌套命名参数的元组做为参数的lambda函数。产生的结果代码有点难以阅读,可是它在Python 3下跟原来的代码在Python 2下的效果是同样的。 你能够定义使用多个参数的lambda函数。若是没有括号包围在参数周围,Python 2会把它看成一个包含多个参数的lambda函数;在这个lambda函数体里,你经过名字引用这些参数,就像在其余类型的函数里所作的同样。这种语法在Python 3里仍然有效。 特殊的方法属性# 在Python 2里,类方法能够访问到定义他们的类对象(class object),也能访问方法对象(method object)自己。im_self是类的实例对象;im_func是函数对象,im_class是类自己。在Python 3里,这些属性被从新命名,以遵循其余属性的命名约定。ip

Notes Python 2 Python 3 aClassInstance.aClassMethod.im_func aClassInstance.aClassMethod.func aClassInstance.aClassMethod.im_self aClassInstance.aClassMethod.self aClassInstance.aClassMethod.im_class aClassInstance.aClassMethod.self.class nonzero__特殊方法# 在Python 2里,你能够建立本身的类,并使他们可以在布尔上下文(boolean context)中使用。举例来讲,你能够实例化这个类,并把这个实例对象用在一个if语句中。为了实现这个目的,你定义一个特别的__nonzero()方法,它的返回值为True或者False,当实例对象处在布尔上下文中的时候这个方法就会被调用 。在Python 3里,你仍然能够完成一样的功能,可是这个特殊方法的名字变成了__bool__()。unicode

Notes Python 2 Python 3 ① class A: def nonzero(self): pass class A: def bool(self): pass ② class A: def nonzero(self, x, y): pass no change 当在布尔上下文使用一个类对象时,Python 3会调用__bool__(),而非__nonzero__()。 然而,若是你有定义了一个使用两个参数的__nonzero__()方法,2to3脚本会假设你定义的这个方法有其余用处,所以不会对代码作修改。 八进制类型# 在Python 2和Python 3之间,定义八进制(octal)数的语法有轻微的改变。

Notes Python 2 Python 3 x =0755 x =0o755 sys.maxint# 因为长整型和整型被整合在一块儿了,sys.maxint常量再也不精确。可是由于这个值对于检测特定平台的能力仍是有用处的,因此它被Python 3保留,而且重命名为sys.maxsize。

Notes Python 2 Python 3 ① from sys importmaxint from sys importmaxsize ② a_function(sys.maxint) a_function(sys.maxsize) maxint变成了maxsize。 全部的sys.maxint都变成了sys.maxsize。 全局函数callable()# 在Python 2里,你可使用全局函数callable()来检查一个对象是否可调用(callable,好比函数)。在Python 3里,这个全局函数被取消了。为了检查一个对象是否可调用,能够检查特殊方法__call__()的存在性。

Notes Python 2 Python 3 callable(anything) hasattr(anything,'call') 全局函数zip()# 在Python 2里,全局函数zip()可使用任意多个序列做为参数,它返回一个由元组构成的列表。第一个元组包含了每一个序列的第一个元素;第二个元组包含了每一个序列的第二个元素;依次递推下去。在Python 3里,zip()返回一个迭代器,而非列表。

Notes Python 2 Python 3 ① zip(a, b, c) list(zip(a, b, c)) ② d.join(zip(a, b, c)) no change 最简单的形式,你能够经过调用list()函数包装zip()的返回值来恢复zip()函数之前的功能,list()函数会遍历这个zip()函数返回的迭代器,而后返回结果的列表表示。 在已经会遍历序列全部元素的上下文环境里(好比这里对join()方法的调用),zip()返回的迭代器可以正常工做。2to3脚本会检测到这些状况,不会对你的代码做出改变。 StandardError异常# 在Python 2里,StandardError是除了StopIteration,GeneratorExit,KeyboardInterrupt,SystemExit以外全部其余内置异常的基类。在Python 3里,StandardError已经被取消了;使用Exception替代。

Notes Python 2 Python 3 x =StandardError() x =Exception() x =StandardError(a, b, c) x =Exception(a, b, c) types模块中的常量# types模块里各类各样的常量能帮助你决定一个对象的类型。在Python 2里,它包含了表明全部基本数据类型的常量,如dict和int。在Python 3里,这些常量被已经取消了。只须要使用基础类型的名字来替代。

Notes Python 2 Python 3 types.UnicodeType str types.StringType bytes types.DictType dict types.IntType int types.LongType int types.ListType list types.NoneType type(None) types.BooleanType bool types.BufferType memoryview types.ClassType type types.ComplexType complex types.EllipsisType type(Ellipsis) types.FloatType float types.ObjectType object types.NotImplementedType type(NotImplemented) types.SliceType slice types.TupleType tuple types.TypeType type types.XRangeType range ☞types.StringType被映射为bytes,而非str,由于Python 2里的“string”(非Unicode编码的字符串,即普通字符串)事实上只是一些使用某种字符编码的字节序列(a sequence of bytes)。 全局函数isinstance()# isinstance()函数检查一个对象是不是一个特定类(class)或者类型(type)的实例。在Python 2里,你能够传递一个由类型(types)构成的元组给isinstance(),若是该对象是元组里的任意一种类型,函数返回True。在Python 3里,你依然能够这样作,可是不推荐使用把一种类型做为参数传递两次。

Notes Python 2 Python 3 isinstance(x,(int,float,int)) isinstance(x,(int,float)) basestring数据类型# Python 2有两种字符串类型:Unicode编码的字符串和非Unicode编码的字符串。可是其实还有另外 一种类型,即basestring。它是一个抽象数据类型,是str和unicode类型的超类(superclass)。它不能被直接调用或者实例化,可是你能够把它做为isinstance()的参数来检测一个对象是不是一个Unicode字符串或者非Unicode字符串。在Python 3里,只有一种字符串类型,因此basestring就没有必要再存在了。

Notes Python 2 Python 3 isinstance(x, basestring) isinstance(x, str) itertools模块# Python 2.3引入了itertools模块,它定义了全局函数zip(),map(),filter()的变体(variant),这些变体的返回类型为迭代器,而非列表。在Python 3里,因为这些全局函数的返回类型原本就是迭代器,因此这些itertools里的这些变体函数就被取消了。(在itertools模块里仍然还有许多其余的有用的函数,而不只仅是以上列出的这些。)

Notes Python 2 Python 3 ① itertools.izip(a, b) zip(a, b) ② itertools.imap(a, b) map(a, b) ③ itertools.ifilter(a, b) filter(a, b) ④ from itertools import imap, izip, foo from itertools import foo 使用全局的zip()函数,而非itertools.izip()。 使用map()而非itertools.imap()。 itertools.ifilter()变成了filter()。 itertools模块在Python 3里仍然存在,它只是再也不包含那些已经转移到全局名字空间的函数。2to3脚本可以足够智能地去移除那些再也不有用的导入语句,同时保持其余的导入语句的完整性。 sys.exc_type, sys.exc_value, sys.exc_traceback# 处理异常的时候,在sys模块里有三个你能够访问的变量:sys.exc_type,sys.exc_value,sys.exc_traceback。(实际上这些在Python 1的时代就有。)从Python 1.5开始,因为新出的sys.exc_info,再也不推荐使用这三个变量了,这是一个包含全部以上三个元素的元组。在Python 3里,这三个变量终于再也不存在了;这意味着,你必须使用sys.exc_info。

Notes Python 2 Python 3 sys.exc_type sys.exc_info()[0] sys.exc_value sys.exc_info()[1] sys.exc_traceback sys.exc_info()[2] 对元组的列表解析# 在Python 2里,若是你须要编写一个遍历元组的列表解析,你不须要在元组值的周围加上括号。在Python 3里,这些括号是必需的。

Notes Python 2 Python 3 [i for iin 1,2] [i for iin (1,2)] os.getcwdu()函数# Python 2有一个叫作os.getcwd()的函数,它将当前的工做目录做为一个(非Unicode编码的)字符串返回。因为现代的文件系统可以处理能何字符编码的目录名,Python 2.3引入了os.getcwdu()函数。os.getcwdu()函数把当前工做目录用Unicode编码的字符串返回。在Python 3里,因为只有一种字符串类型(Unicode类型的),因此你只须要os.getcwd()就能够了。

Notes Python 2 Python 3 os.getcwdu() os.getcwd() 元类(metaclass)# 在Python 2里,你能够经过在类的声明中定义metaclass参数,或者定义一个特殊的类级别的(class-level)__metaclass__属性,来建立元类。在Python 3里,__metaclass__属性已经被取消了。

Notes Python 2 Python 3 ① class C(metaclass=PapayaMeta): pass unchanged ② class Whip: metaclass = PapayaMeta class Whip(metaclass=PapayaMeta): pass ③ class C(Whipper, Beater): metaclass = PapayaMeta class C(Whipper, Beater, metaclass=PapayaMeta): pass 在声明类的时候声明metaclass参数,这在Python 2和Python 3里都有效,它们是同样的。 在类的定义里声明__metaclass__属性在Python 2里有效,可是在Python 3里再也不有效。 2to3可以构建一个有效的类声明,即便这个类继承自多个父类。

相关文章
相关标签/搜索