python2 和python3 的区别

原文:https://www.cnblogs.com/meng-wei-zhi/articles/8194849.html

 

几乎所有的python2程序都需要一些修改才能正常的运行在python3的环境下。为了简化这个转换过程,Python3自带了一个2to3的实用脚本.这个脚本会将python2程序源文件作为输入,然后自动转换到python3.但并不是所有内容都可以自动转换。

print语句

python2中print是一个语句,不论想输出什么,直接放到print关键字后面即可。python3里,print()是一个函数,像其他函数一样,print()需要你将要输出的东西作为参数传给它。

python2python3备注
printprint()输出一个空白行,python3需要调用不带参数的print()
print 1print(1)输出一个值,将值传入print()函数
print 1, 2print(1,2)输出使用空格分割的两个值,使用两个参数调用print()
print 1, 2,print(1,2, end=' ')python2中如果使用一个,作为print结尾,将会用空格分割输出的结果,然后在输出一个尾随的空格,而不输回车。python3里,把end=' ' 作为一个关键字传给print()可以实现同样的效果,end默认值为'\n',所以通过重新指定end参数的值,可以取消在末尾输出回车符号
print >> sys.stderr, 1, 2, 3print(1, 2, 3, file=sys.stderrpython2中,可以通过>>pipe_name语法,把输出重定向到一个管道,比如sys.stderr.在python3里,可以通过将管道作为关键字参数file的值传递给print()完成同样的功能。

UNICODE字符串

python2中有两种字符串类型:Unicode字符串和非Unicode字符串。Python3中只有一种类型:Unicode字符串。

python2python3备注
u'PapayaWhip''PapayaWhip'python2中的Unicode字符串在python3即为普通字符串
ur'PapayaWhip\foo'r'PapayWhip\foo'Unicode原始字符串(使用这种字符串,python不会自动转义反斜线"\")也被替换为普通的字符串,因为在python3里,所有原始字符串都是以unicode编码的。

全局函数UNICODE()

python2有两个全局函数可以把对象强制转换成字符串:unicode()把对象转换成unicode字符串,还有str()把对象转换为非Unicode字符串。Python3只有一种字符串类型,unicode字符串,所以str()函数即可完成所有的功能。

LONG长整型

python2有非浮点数准备的int和long类型。int类型最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。在python3里,只有一种整数类型int,大多数情况下,和python2中的长整型类似。

python2python3备注
x = 1000000000000Lx = 1000000000000python2中的十进制长整型在python3中被替换为十进制普通整数
x = 0xFFFFFFFFFFFFLx = 0xFFFFFFFFFFFFpython2里的十六进制长整型在python3里被替换为十六进制的普通整数
long(x)int(x)python3没有long()
type(x) is longtype(x) is intpython3用int判断是否为整型
isinstance(x, long)isinstance(x, int)int检查整数类型

<>比较运算符

Python2支持<>作为!=的同义词, python3只支持!=, 不再支持<>

字典类方法HAS_KEY()

Python2中,字典对象has_key()方法测试字典是否包含指定的键。python3不再支持这个方法,需要使用in.

返回列表的字典类方法

在python2里,许多字典类方法的返回值是列表。最常用方法有keys, items和values。python3,所有以上方法的返回值改为动态试图。在一些上下文环境里,这种改变不会产生影响。如果这些方法的返回值被立即传递给另外一个函数,而且那个函数会遍历整个序列,那么以上方法的返回值是列表或视图并不会产生什么不同。如果你期望获得一个被独立寻址元素的列表,那么python3的这些改变将会使你的代码卡住,因为视图不支持索引。

python2python3备注
a_dictionary.keys()list(a_dictionary.keys())使用list()将keys 返回值转换为一个静态列表
a_dictionary.items()list(a_dictonary.items())将items返回值转为列表
a_dictionary.iterkeys()iter(a_dictionary.keys())python3不再支持iterkeys,使用iter()将keys()的返回值转换为一个迭代器
[i for i in a_dictionary.iterkeys()][ i for i in a_dictonary.keys()]不需要使用额外的iter(),keys()方法返回的是可迭代的
min(a_dictionary.keys())no change对min(),max(),sum(),list(),tuple(),set(),sorted(),any()和all()同样有效

重命名或重新组织的模块

从python2到python3,标准库里的一些模块已经被重命名。还有一些相互关联的模块也被组合或则重新组织,使得这种关联更有逻辑性。

HTTP

python3中几个相关的http模块被组合成一个单独的包,即http

python2python3备注
import httplibimport http.clienthttp.client模块实现一个底层的库,可以用来请求和解析http
import cookieimport http.cookieshttp.cookie提供一个pythonic接口进行cookies操作
import cookielibimport http.cookiejarhttp.cookiejar可以操作cookies文件
import BaseHTTPServer import SimpleHTTPServer import CGIHttpServerimport http.serverhttp.server实现了一个基本的http服务器

URLLIB

python2中用来分析、编码和获取URL的模块,但是比较混乱,python3中,这些模块被重构,组合成为一个单独的包,即urllib

| python2 | python3 | 备注 | import urllib | import urllib.request, import urllb.parse, import urllib.error | | import urllib2 | import urllib.request, urllib.error | | import urlparse | import urllib.parse | | import robotparser | import urllib.robotparser | | from urllib import FancyURLopener | from urllib.rquest import FancyURLopener from urllib.parse | |from urllib2 import Request from urllib2 import HTTPError | from urllib.request import Request from urllib.error import HTTPError |

DBM

所有的DBM现在都在一个单独的包里,即dbm。如果需要其中某个特定的变体,比如GNU DBM,可以导入dbm包中合适的模块。

python2python3备注
import dbmimport dbm.ndbm 
import gdbmimport dbm.gnu 
import dbhashimport dbm.bad 
import dumbdbmimport dbm.dumb 
import anydbm import whichdbimport dbm 

XMLRPC

XML-RPC是一个通过HTTP协议执行远程RPC调用的轻重级方法。一些XML_RPC客户端和XML_RPC服务端的实现库组合成独立的包,xmlrpc.

python2python3备注
import xmlrpclibimport xmlrpc.client 
import DocXMLRPCServer import SimpleXMLRPCServerimport xmlrpc.server 

其他模块

Python2python3备注
try: import cStringIO as StringIO except ImportError: import STringIOimport io 
try: import cPickle as pickle except ImportError: import pickleimport pickle 
import builtinimport builtins 
import copy_regimport copyreg 
import Queueimport queue 
import SocketServerimport socketserver 
import ConfigParserimport configparser 
import reprimport reprlib 
import commandsimport subprocess 

包内的相对导入

包是由一组相关联的模块共同组成的单个实体。在python2的时候,为了实现同一个包内模块的相互引用,你会使用import foo或者from foo import Bar。Python2解释器会先在当前目录里搜索foo.py,然后再去python搜索路径(sys.path)搜索。在python3里这个过程有一点不同。Python3不会首先在当前路径搜索,它会直接在Python的搜索路径里寻找。如果想要包里的一个模块导入包的另一个模块,需要显式的提供两个模块的相对路径。

迭代器方法NEXT()

python2里,迭代器有一个next()方法,用来返回序列的下一项。在python3里同样成立。但是有一个新的全局的函数next(),它使用一个迭代器作为参数。

python2python3备注
anIterator.next()next(anIterator) 
a_function_that_returns_an_iterator().next()next(a_function_that_returns_an_iterator()) 
class A: def next(self): passclass A : def next(self): pass 
class A: def next(self, x, y): passno change 
next = 42 for an_iterator in a_sequence_of_iterators: an_iterator.next()next =42 for an interator in a_sequence_of_iterators: an_iterator.next() 

全局函数FILTER()

在python2里,filter()方法返回一个列表,这个列表是通过一个返回值为True或False的函数来检测序列里的每一项的道德。在python3中,filter()函数返回一个迭代器,不再是列表。

python2python3备注
filter(a_function, a_sequence)list(filter(a_function, a_sequence)) 
list(filter(a_function, a_sequence))no change 
filter(None, a_sequence)[i for i in a_sequence if i ] 
for i in filter(None, a_sequence):no change 
[i for i in filter(a_function, a_sequence)]no change 

MAP()

跟filter()的改变一样,map()函数现在返回一个迭代器,python2中返回一个列表。

python2python3备注
map(a_function,'PapayaWhip'list(map(a_function, 'PapayaWhip')) 
map(None, 'PapayaWhip'list('PapayWhip') 
map(lambda x: x+1, range(42))[x+1 for x in range(42)] 
for i in map(a_function, a_sequence):no change 
[i for i in map(a_function, a_sequence)]no change 

REDUCE()

在python3里,reduce()函数已经从全局名字空间移除,现在被放置在fucntools模块里。

python2python3备注
reduce(a,b,c)from functools import reduce reduce(a, b, c) 

APPLY()

python2有一个叫做apply()的全局函数,它使用一个函数f和一个列表[a,b,c]作为参数,返回值是f(a,b,c).可以直接调用这个函数,在列表前添加一个星号作为参数传递给它来完成同样的事情。在python3里,apply()函数不再存在;必须使用星号标记。

python2python3备注
apply(a_function, a_list_of_argsa_function(*a_list_of_args) 
apply(a_function, a_list_of_args, a_dictionary_of_named_args)a_function(*a_list_of_args, **a_dictionary_of_named_args) 
apply(a_function, a_list_of_args + z)a_function(*a_list_of_args + z) 
apply(aModule.a_function, a_list_of_args)aModule.a_function(*a_list_of_args) 

INTERN()   python2里,你可以用intern()函数作用在一个字符串上来限定intern以达到性能优化,python3里,intern()函数转移到sys模块里。

python2python3备注
intern(aString)sys.intern(aString)--------

EXEC

就像print语句在python3里变成了一个函数一样,exec语句也是这样的。exec()函数使用一个包含任意python代码的字符串作为参数,然后像执行语句或表达式一样执行它。exec()跟eval()是相似,但exec()更加强大并具有挑战性。eval()函数只能执行单独一条表达式,但是exec()能够执行多条语句,导入(import),函数声明-实际上整个python程序的字符串表示也可以。

python2python3备注
exec codeStringexec(codeString) 
exec codeString in a_global_namespaceexec(codeString, a_global_namespace) 
exec_codeString in a_global_namespace, a_local_namespaceexec(codeString, a_global_namespace, a_local_namespace 

execfile

python2中的execfile语句可以像执行python代码那样使用字符串。不同的是exec使用字符串,而execfile使用文件。在python3,execfile语句被去掉了。

REPR

在python2,为了得到一个任意对象的字符串表示,有一种把对象包装在反引号里(比如x)的特殊语法。在python3里,这种能力仍然存在,但是你不能再使用反引号获得这种字符串表示了,需要使用全局函数repr().

python2python3备注
xrepr(x) 
'PapayaWhip' +2repr('PapayWhip' + repr(2)) 

TRYEXCEPT语句

python2到python3,捕获异常的语法有些变化。

Python2Python3备注
try: import mymodule except ImportError, e passtry: import mymodule except ImportError as e: pass 
try: import mymodule except (RuntimeError, ImportError), e passtry: import mymodule except(RuntimeError, ImportError) as e: pass 
try: import mymodule except ImportError: passno change 
try: import mymodule except: passno change 

RAISE

python3里,抛出自定义异常的语法有细微的变化。

python2python3备注
raise MyExceptionunchanged 
raise MyException, 'error message'raise MyException('error message') 
raise MyException, 'error message'raise MyException('error message').with_traceback(a_traceback) 
raise 'error message'unsupported 

生成器THROW

在python2里,生成器有一个throw()方法。调用a_generator.throw()会在生成器被暂停的时候抛出异常,然后返回由生成器函数获取的下一个值。python3中,这一功能仍然可用,但语法有一点不同。

python2python3备注
a_generator.throw(MyException)no change 
a_generator.throw(MyException, 'error message'a_generator.throw(MyException('error message')) 
a_generator.throw('error message')unsupported 

XRANGE()

python2里,有两种方法获得一定范围内的数字:range(),返回一个列表,还有xrange(),返回一个迭代器。python3 里,range()返回迭代器,xrange()不再存在。

 

python2python3备注
xrange(10)range(10) 
a_list = range(10)a_list= list(range(10)) 
[i for i in xrange(10)][i for i in range(10)] 
for i in range(10):no change 
sum(range(10))

no change

 

 

RAW_INPUT()和INPUT()

 

python2有两个全局函数,用在命令行请求用户输入。第一个叫input(),它等待用户输入一个python表达式(然后返回结果)。第二个叫做raw_input(),用户输入什么他就返回什么。python3 通过input替代了他们。

python2python3备注
raw_input()inputinput替代了raw_input
raw_input('prompt')input('prompt')python3仍然支持提示符参数
input()eval(input)) 

函数属性FUNC_*

python2,函数的代码可用访问到函数本身的特殊属性。python3为了一致性,这些特殊属性被重命名了。

python2python3备注
a_function.func_namea_function.__name____name__属性包含了函数的名字
a_function.func_doca_function.__doc____doc__包含了函数源代码定义的文档字符串
a_function.func_defaultsa_function.__defaults__是一个保存参数默认值的元组
a_function.func_dicta_function.__dict____dict__属性是一个支持任意函数属性的名字空间
a_function.func_closurea_function.__closure____closure__属性是由cell对象组成的元组,包含了函数对自由变量的绑定
a_function.func_globalsa_function.__globals__是对模块全局名字空间的引用
a_function.func_codea_function.__code__是一个代码对象,表示编译后的函数体

I/O方法XREADLINES()

python2中,文件对象有一个xreadlines()方法,返回一个迭代器,一次读取文件的一行。这在for循环中尤其实用。python3中,xreadlines()方法不再可用。

lambda函数

在python2中,可以定义匿名函数lambda函数,通过指定作为参数的元组的元素个数,使这个函数实际上能够接收多个参数。python2的解释器把这个元组"解开“成命名参数,然后可以在lambda函数里引用它们。在python3中仍然可以传递一个元组为lambda函数的参数。但是python解释器不会把它当成解析成命名参数。需要通过位置索引来引用每个参数。

python2python3备注
lambda (x,): x + f(x)lambda x1 : x1[0] + f(x1[0])注1
lambda (x,y): x + f(y)lambda x_y : x_y[0] + f(x_y[1])注2
lambda (x,(y,z)): x + y + zlambda x_y_z: x_y_z[0] + x_y_z[1][0]+ x_y_z[1][1]注3
lambda x,y,z: x+y+zunchanged注4

注1:如果定义了一个lambda函数,使用包含一个元素的元组作为参数,python3中,会被转换成一个包含到x1[0]的引用的lambda函数。x1是2to3脚本基于原来元组里的命名参数自动生成的。

注2:使用含有两个元素的元组(x,y)作为参数的lambda函数被转换为x_y,它有两个位置参数,即x_y[0]和x_y[1]

注3:2to3脚本可以处理使用嵌套命名参数的元组作为参数的lambda函数。产生的结果有点晦涩,但python3下和python2的效果是一样的。

注4:可以定义使用多个参数的lambda函数。语法在python3同样有效

特殊的方法属性

在python2里,类方法可以访问到定义他们的类对象,也能访问方法对象本身。im_self是类的实例对象;im_func是函数对象,im_class是类本身。在python3里,这些属性被重命名,以遵循其他属性的命名约定。

python2python3
aClassInstance.aClassMethod.im_funcaClassInstance.aClassMethod.__func__
aClassInstance.aClassMethod.im_selfaClassInstance.aClassMethod.__self__
aClassInstance.aClassMethod.im_classaClassInstance.aClassMethod.__self__.__class__

__NONZERO__特殊方法

在python2里,可以创建自己的类,并使他们能够在布尔上下文中使用。举例来说,可以实例化这个类,并把这个实例对象用在一个if语句中。为了实现这个目的,可以定义一个特别的__nonzero__()方法,它的返回值为True或False,当实例对象处在布尔上下文中的时候这个方法就会被调用。在python3中,仍然可以完成同样的功能,但这个特殊方法的名字改为了__bool__()

比如python2中

class A:
    def __nonzero__(self):
        pass

python3中改为:   class A: def bool(self): pass

在布尔上下文使用一个类对象时,python3会调用__bool__().

python2中:

class A:
    def __nonzero__(self, x, y):
         pass

这种情况python3中不做改变,使用两个参数的__nonzero__()方法,2to3脚本会假设你定义的这个方法有其他用处,不做修改。

八进制类型

python2和python3,定义八进制数的语法有轻微的改变

python2python3
x= 0755x = 0o755

SYS.MAXINT

python3中长整型和整型被整合到一起,sys.maxint常量不再精确。但是因为这个值用于检查特定平台,所以被python3保留,重命名为sys.maxsize.

全局函数CALLABLE()

python2里,可以使用全局函数callable()来检查一个对象是否可调用,在python3中,这个全局函数被取消了,为了检查一个对象是否可调用,可以检查其特殊方法__call__()的存在性。

python2python3
callable(anthing)hasattr(anything, '__call__')

全局函数ZIP()

在python2,zip()可以使用任意多个序列作为参数,它返回一个由元组构成的列表。第一个元组包含了每个序列的第一个元素,第二个元组包含了每个序列的第二个元素,依次递推。在python3中返回一个迭代器,而非列表。

python2python3note
zip(a,b,c)list(zip(a,b,c)python3中可以通过list函数遍历zip()返回的迭代器,形成列表返回
d.join(zip(a,b,c))no change在已经会遍历所有元素的上下文环境里,zip()本身返回的迭代器能够正常工作,2to3脚本检测到后,不再修改

STANDARDERROR异常

python2中,StandardError是除了StopIteration,GeneratorExit,KeyboardInterrupt, SystemExit之外所有其他内置异常的基类。python3中StandardError已经被取消了,使用Exception取代。

TYPES模块中的常量

types模块里各种各样的常量能够帮助你决定一个对象的类型。在python2里,它包含了代表所有基本数据类型的常量,如dict和int。在python3里,这些常量被取消了,只需使用基础类型的名字来替代。

python2python3
types.UnicodeTypestr
types.StringTypebytes
types.DictTypedict
types.IntTypeint
types.LongTypeint
types.ListTypelist
types.NoneTypetype(None
types.BooleanTypebool
types.BufferTypememoryview
types.ClassTypetype
types.ComplexTypecomplex
types.EllipsisTypetype(Ellipsis)
types.FloatTypefloat
types.ObjectTypeobject
types.NotImplementedTypetype(NotImplemented)
types.SliceTypeslice
types.TupleTypetuple
types.TypeTypetype
types.XRangeTyperange

全局函数ISINSTANCE()

isinstance()函数检查一个对象是否是一个特定类(class)或类型(type)的实例。在python2,可以传递一个由类型构成的元组给isinstance(),如果该对象是元组里的任意一种类型,函数返回True. 在python3,依然可以这样做。

python2python3
isinstance(x, (int, float, int))isinstance(x, (int, float))

ITERTOOLS模块

python2.3引入itertools模块,定义了zip(),map(),filter()的变体,这个变体返回的是迭代器,而非列表。在python3,这些函数返回的本身就是迭代器,所有这些变体函数就取消了。

SYS.EXC_TYPE,SYS.EXC_VALUE,SYS.EXC_TRACEBACK

处理异常的时候,在sys模块里有三个你可以访问的变量:sys.exc_type, sys.exc_value, sys.exc_traceback. python3中这三个变量不再存在,使用sys.exc_info替代。

对元组的列表解析

python2,如果需要编写一个遍历元组的列表解析,不需要在元组值周围加上括号。在python3里,这些括号是必需的。

python2python3
[ i for i in 1, 2][i for i in (1,2)]

元类

在python2里,可以通过在类的声明中定义metaclass参数,或者定义一个特殊的类级别(class-level)__metaclass__属性,来创建元类。python3中,__metaclass__属性被取消了。

python2python3note
class C(metaclass=PapayaMeta): passunchanged 
class Whip: __metaclass__ = PapayMetaclass Whip(metaclass=PapayaMeta): pass 
class C(Whipper, Beater): __metaclass__ = PapayaMetaclass C(Whipper, Beater, metaclass=PapayMeta): pass

几乎所有的python2程序都需要一些修改才能正常的运行在python3的环境下。为了简化这个转换过程,Python3自带了一个2to3的实用脚本.这个脚本会将python2程序源文件作为输入,然后自动转换到python3.但并不是所有内容都可以自动转换。

print语句

python2中print是一个语句,不论想输出什么,直接放到print关键字后面即可。python3里,print()是一个函数,像其他函数一样,print()需要你将要输出的东西作为参数传给它。

python2python3备注
printprint()输出一个空白行,python3需要调用不带参数的print()
print 1print(1)输出一个值,将值传入print()函数
print 1, 2print(1,2)输出使用空格分割的两个值,使用两个参数调用print()
print 1, 2,print(1,2, end=' ')python2中如果使用一个,作为print结尾,将会用空格分割输出的结果,然后在输出一个尾随的空格,而不输回车。python3里,把end=' ' 作为一个关键字传给print()可以实现同样的效果,end默认值为'\n',所以通过重新指定end参数的值,可以取消在末尾输出回车符号
print >> sys.stderr, 1, 2, 3print(1, 2, 3, file=sys.stderrpython2中,可以通过>>pipe_name语法,把输出重定向到一个管道,比如sys.stderr.在python3里,可以通过将管道作为关键字参数file的值传递给print()完成同样的功能。

UNICODE字符串

python2中有两种字符串类型:Unicode字符串和非Unicode字符串。Python3中只有一种类型:Unicode字符串。

python2python3备注
u'PapayaWhip''PapayaWhip'python2中的Unicode字符串在python3即为普通字符串
ur'PapayaWhip\foo'r'PapayWhip\foo'Unicode原始字符串(使用这种字符串,python不会自动转义反斜线"\")也被替换为普通的字符串,因为在python3里,所有原始字符串都是以unicode编码的。

全局函数UNICODE()

python2有两个全局函数可以把对象强制转换成字符串:unicode()把对象转换成unicode字符串,还有str()把对象转换为非Unicode字符串。Python3只有一种字符串类型,unicode字符串,所以str()函数即可完成所有的功能。

LONG长整型

python2有非浮点数准备的int和long类型。int类型最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。在python3里,只有一种整数类型int,大多数情况下,和python2中的长整型类似。

python2python3备注
x = 1000000000000Lx = 1000000000000python2中的十进制长整型在python3中被替换为十进制普通整数
x = 0xFFFFFFFFFFFFLx = 0xFFFFFFFFFFFFpython2里的十六进制长整型在python3里被替换为十六进制的普通整数
long(x)int(x)python3没有long()
type(x) is longtype(x) is intpython3用int判断是否为整型
isinstance(x, long)isinstance(x, int)int检查整数类型

<>比较运算符

Python2支持<>作为!=的同义词, python3只支持!=, 不再支持<>

字典类方法HAS_KEY()

Python2中,字典对象has_key()方法测试字典是否包含指定的键。python3不再支持这个方法,需要使用in.

返回列表的字典类方法

在python2里,许多字典类方法的返回值是列表。最常用方法有keys, items和values。python3,所有以上方法的返回值改为动态试图。在一些上下文环境里,这种改变不会产生影响。如果这些方法的返回值被立即传递给另外一个函数,而且那个函数会遍历整个序列,那么以上方法的返回值是列表或视图并不会产生什么不同。如果你期望获得一个被独立寻址元素的列表,那么python3的这些改变将会使你的代码卡住,因为视图不支持索引。

python2python3备注
a_dictionary.keys()list(a_dictionary.keys())使用list()将keys 返回值转换为一个静态列表
a_dictionary.items()list(a_dictonary.items())将items返回值转为列表
a_dictionary.iterkeys()iter(a_dictionary.keys())python3不再支持iterkeys,使用iter()将keys()的返回值转换为一个迭代器
[i for i in a_dictionary.iterkeys()][ i for i in a_dictonary.keys()]不需要使用额外的iter(),keys()方法返回的是可迭代的
min(a_dictionary.keys())no change对min(),max(),sum(),list(),tuple(),set(),sorted(),any()和all()同样有效

重命名或重新组织的模块

从python2到python3,标准库里的一些模块已经被重命名。还有一些相互关联的模块也被组合或则重新组织,使得这种关联更有逻辑性。

HTTP

python3中几个相关的http模块被组合成一个单独的包,即http

python2python3备注
import httplibimport http.clienthttp.client模块实现一个底层的库,可以用来请求和解析http
import cookieimport http.cookieshttp.cookie提供一个pythonic接口进行cookies操作
import cookielibimport http.cookiejarhttp.cookiejar可以操作cookies文件
import BaseHTTPServer import SimpleHTTPServer import CGIHttpServerimport http.serverhttp.server实现了一个基本的http服务器

URLLIB

python2中用来分析、编码和获取URL的模块,但是比较混乱,python3中,这些模块被重构,组合成为一个单独的包,即urllib

| python2 | python3 | 备注 | import urllib | import urllib.request, import urllb.parse, import urllib.error | | import urllib2 | import urllib.request, urllib.error | | import urlparse | import urllib.parse | | import robotparser | import urllib.robotparser | | from urllib import FancyURLopener | from urllib.rquest import FancyURLopener from urllib.parse | |from urllib2 import Request from urllib2 import HTTPError | from urllib.request import Request from urllib.error import HTTPError |

DBM

所有的DBM现在都在一个单独的包里,即dbm。如果需要其中某个特定的变体,比如GNU DBM,可以导入dbm包中合适的模块。

python2python3备注
import dbmimport dbm.ndbm 
import gdbmimport dbm.gnu 
import dbhashimport dbm.bad 
import dumbdbmimport dbm.dumb 
import anydbm import whichdbimport dbm 

XMLRPC

XML-RPC是一个通过HTTP协议执行远程RPC调用的轻重级方法。一些XML_RPC客户端和XML_RPC服务端的实现库组合成独立的包,xmlrpc.

python2python3备注
import xmlrpclibimport xmlrpc.client 
import DocXMLRPCServer import SimpleXMLRPCServerimport xmlrpc.server 

其他模块

Python2python3备注
try: import cStringIO as StringIO except ImportError: import STringIOimport io 
try: import cPickle as pickle except ImportError: import pickleimport pickle 
import builtinimport builtins 
import copy_regimport copyreg 
import Queueimport queue 
import SocketServerimport socketserver 
import ConfigParserimport configparser 
import reprimport reprlib 
import commandsimport subprocess 

包内的相对导入

包是由一组相关联的模块共同组成的单个实体。在python2的时候,为了实现同一个包内模块的相互引用,你会使用import foo或者from foo import Bar。Python2解释器会先在当前目录里搜索foo.py,然后再去python搜索路径(sys.path)搜索。在python3里这个过程有一点不同。Python3不会首先在当前路径搜索,它会直接在Python的搜索路径里寻找。如果想要包里的一个模块导入包的另一个模块,需要显式的提供两个模块的相对路径。

迭代器方法NEXT()

python2里,迭代器有一个next()方法,用来返回序列的下一项。在python3里同样成立。但是有一个新的全局的函数next(),它使用一个迭代器作为参数。

python2python3备注
anIterator.next()next(anIterator) 
a_function_that_returns_an_iterator().next()next(a_function_that_returns_an_iterator()) 
class A: def next(self): passclass A : def next(self): pass 
class A: def next(self, x, y): passno change 
next = 42 for an_iterator in a_sequence_of_iterators: an_iterator.next()next =42 for an interator in a_sequence_of_iterators: an_iterator.next() 

全局函数FILTER()

在python2里,filter()方法返回一个列表,这个列表是通过一个返回值为True或False的函数来检测序列里的每一项的道德。在python3中,filter()函数返回一个迭代器,不再是列表。

python2python3备注
filter(a_function, a_sequence)list(filter(a_function, a_sequence)) 
list(filter(a_function, a_sequence))no change 
filter(None, a_sequence)[i for i in a_sequence if i ] 
for i in filter(None, a_sequence):no change 
[i for i in filter(a_function, a_sequence)]no change 

MAP()

跟filter()的改变一样,map()函数现在返回一个迭代器,python2中返回一个列表。

python2python3备注
map(a_function,'PapayaWhip'list(map(a_function, 'PapayaWhip')) 
map(None, 'PapayaWhip'list('PapayWhip') 
map(lambda x: x+1, range(42))[x+1 for x in range(42)] 
for i in map(a_function, a_sequence):no change 
[i for i in map(a_function, a_sequence)]no change 

REDUCE()

在python3里,reduce()函数已经从全局名字空间移除,现在被放置在fucntools模块里。

python2python3备注
reduce(a,b,c)from functools import reduce reduce(a, b, c) 

APPLY()

python2有一个叫做apply()的全局函数,它使用一个函数f和一个列表[a,b,c]作为参数,返回值是f(a,b,c).可以直接调用这个函数,在列表前添加一个星号作为参数传递给它来完成同样的事情。在python3里,apply()函数不再存在;必须使用星号标记。

python2python3备注
apply(a_function, a_list_of_argsa_function(*a_list_of_args) 
apply(a_function, a_list_of_args, a_dictionary_of_named_args)a_function(*a_list_of_args, **a_dictionary_of_named_args) 
apply(a_function, a_list_of_args + z)a_function(*a_list_of_args + z) 
apply(aModule.a_function, a_list_of_args)aModule.a_function(*a_list_of_args) 

INTERN()   python2里,你可以用intern()函数作用在一个字符串上来限定intern以达到性能优化,python3里,intern()函数转移到sys模块里。

python2python3备注
intern(aString)sys.intern(aString)--------

EXEC

就像print语句在python3里变成了一个函数一样,exec语句也是这样的。exec()函数使用一个包含任意python代码的字符串作为参数,然后像执行语句或表达式一样执行它。exec()跟eval()是相似,但exec()更加强大并具有挑战性。eval()函数只能执行单独一条表达式,但是exec()能够执行多条语句,导入(import),函数声明-实际上整个python程序的字符串表示也可以。

python2python3备注
exec codeStringexec(codeString) 
exec codeString in a_global_namespaceexec(codeString, a_global_namespace) 
exec_codeString in a_global_namespace, a_local_namespaceexec(codeString, a_global_namespace, a_local_namespace 

execfile

python2中的execfile语句可以像执行python代码那样使用字符串。不同的是exec使用字符串,而execfile使用文件。在python3,execfile语句被去掉了。

REPR

在python2,为了得到一个任意对象的字符串表示,有一种把对象包装在反引号里(比如x)的特殊语法。在python3里,这种能力仍然存在,但是你不能再使用反引号获得这种字符串表示了,需要使用全局函数repr().

python2python3备注
xrepr(x) 
'PapayaWhip' +2repr('PapayWhip' + repr(2)) 

TRYEXCEPT语句

python2到python3,捕获异常的语法有些变化。

Python2Python3备注
try: import mymodule except ImportError, e passtry: import mymodule except ImportError as e: pass 
try: import mymodule except (RuntimeError, ImportError), e passtry: import mymodule except(RuntimeError, ImportError) as e: pass 
try: import mymodule except ImportError: passno change 
try: import mymodule except: passno change 

RAISE

python3里,抛出自定义异常的语法有细微的变化。

python2python3备注
raise MyExceptionunchanged 
raise MyException, 'error message'raise MyException('error message') 
raise MyException, 'error message'raise MyException('error message').with_traceback(a_traceback) 
raise 'error message'unsupported 

生成器THROW

在python2里,生成器有一个throw()方法。调用a_generator.throw()会在生成器被暂停的时候抛出异常,然后返回由生成器函数获取的下一个值。python3中,这一功能仍然可用,但语法有一点不同。

python2python3备注
a_generator.throw(MyException)no change 
a_generator.throw(MyException, 'error message'a_generator.throw(MyException('error message')) 
a_generator.throw('error message')unsupported 

XRANGE()

python2里,有两种方法获得一定范围内的数字:range(),返回一个列表,还有xrange(),返回一个迭代器。python3 里,range()返回迭代器,xrange()不再存在。

 

python2python3备注
xrange(10)range(10) 
a_list = range(10)a_list= list(range(10)) 
[i for i in xrange(10)][i for i in range(10)] 
for i in range(10):no change 
sum(range(10))

no change

 

 

RAW_INPUT()和INPUT()

 

python2有两个全局函数,用在命令行请求用户输入。第一个叫input(),它等待用户输入一个python表达式(然后返回结果)。第二个叫做raw_input(),用户输入什么他就返回什么。python3 通过input替代了他们。

python2python3备注
raw_input()inputinput替代了raw_input
raw_input('prompt')input('prompt')python3仍然支持提示符参数
input()eval(input)) 

函数属性FUNC_*

python2,函数的代码可用访问到函数本身的特殊属性。python3为了一致性,这些特殊属性被重命名了。

python2python3备注
a_function.func_namea_function.__name____name__属性包含了函数的名字
a_function.func_doca_function.__doc____doc__包含了函数源代码定义的文档字符串
a_function.func_defaultsa_function.__defaults__是一个保存参数默认值的元组
a_function.func_dicta_function.__dict____dict__属性是一个支持任意函数属性的名字空间
a_function.func_closurea_function.__closure____closure__属性是由cell对象组成的元组,包含了函数对自由变量的绑定
a_function.func_globalsa_function.__globals__是对模块全局名字空间的引用
a_function.func_codea_function.__code__是一个代码对象,表示编译后的函数体

I/O方法XREADLINES()

python2中,文件对象有一个xreadlines()方法,返回一个迭代器,一次读取文件的一行。这在for循环中尤其实用。python3中,xreadlines()方法不再可用。

lambda函数

在python2中,可以定义匿名函数lambda函数,通过指定作为参数的元组的元素个数,使这个函数实际上能够接收多个参数。python2的解释器把这个元组"解开“成命名参数,然后可以在lambda函数里引用它们。在python3中仍然可以传递一个元组为lambda函数的参数。但是python解释器不会把它当成解析成命名参数。需要通过位置索引来引用每个参数。

python2python3备注
lambda (x,): x + f(x)lambda x1 : x1[0] + f(x1[0])注1
lambda (x,y): x + f(y)lambda x_y : x_y[0] + f(x_y[1])注2
lambda (x,(y,z)): x + y + zlambda x_y_z: x_y_z[0] + x_y_z[1][0]+ x_y_z[1][1]注3
lambda x,y,z: x+y+zunchanged注4

注1:如果定义了一个lambda函数,使用包含一个元素的元组作为参数,python3中,会被转换成一个包含到x1[0]的引用的lambda函数。x1是2to3脚本基于原来元组里的命名参数自动生成的。

注2:使用含有两个元素的元组(x,y)作为参数的lambda函数被转换为x_y,它有两个位置参数,即x_y[0]和x_y[1]

注3:2to3脚本可以处理使用嵌套命名参数的元组作为参数的lambda函数。产生的结果有点晦涩,但python3下和python2的效果是一样的。

注4:可以定义使用多个参数的lambda函数。语法在python3同样有效

特殊的方法属性

在python2里,类方法可以访问到定义他们的类对象,也能访问方法对象本身。im_self是类的实例对象;im_func是函数对象,im_class是类本身。在python3里,这些属性被重命名,以遵循其他属性的命名约定。

python2python3
aClassInstance.aClassMethod.im_funcaClassInstance.aClassMethod.__func__
aClassInstance.aClassMethod.im_selfaClassInstance.aClassMethod.__self__
aClassInstance.aClassMethod.im_classaClassInstance.aClassMethod.__self__.__class__

__NONZERO__特殊方法

在python2里,可以创建自己的类,并使他们能够在布尔上下文中使用。举例来说,可以实例化这个类,并把这个实例对象用在一个if语句中。为了实现这个目的,可以定义一个特别的__nonzero__()方法,它的返回值为True或False,当实例对象处在布尔上下文中的时候这个方法就会被调用。在python3中,仍然可以完成同样的功能,但这个特殊方法的名字改为了__bool__()

比如python2中

class A:
    def __nonzero__(self):
        pass

python3中改为:   class A: def bool(self): pass

在布尔上下文使用一个类对象时,python3会调用__bool__().

python2中:

class A:
    def __nonzero__(self, x, y):
         pass

这种情况python3中不做改变,使用两个参数的__nonzero__()方法,2to3脚本会假设你定义的这个方法有其他用处,不做修改。

八进制类型

python2和python3,定义八进制数的语法有轻微的改变

python2python3
x= 0755x = 0o755

SYS.MAXINT

python3中长整型和整型被整合到一起,sys.maxint常量不再精确。但是因为这个值用于检查特定平台,所以被python3保留,重命名为sys.maxsize.

全局函数CALLABLE()

python2里,可以使用全局函数callable()来检查一个对象是否可调用,在python3中,这个全局函数被取消了,为了检查一个对象是否可调用,可以检查其特殊方法__call__()的存在性。

python2python3
callable(anthing)hasattr(anything, '__call__')

全局函数ZIP()

在python2,zip()可以使用任意多个序列作为参数,它返回一个由元组构成的列表。第一个元组包含了每个序列的第一个元素,第二个元组包含了每个序列的第二个元素,依次递推。在python3中返回一个迭代器,而非列表。

python2python3note
zip(a,b,c)list(zip(a,b,c)python3中可以通过list函数遍历zip()返回的迭代器,形成列表返回
d.join(zip(a,b,c))no change在已经会遍历所有元素的上下文环境里,zip()本身返回的迭代器能够正常工作,2to3脚本检测到后,不再修改

STANDARDERROR异常

python2中,StandardError是除了StopIteration,GeneratorExit,KeyboardInterrupt, SystemExit之外所有其他内置异常的基类。python3中StandardError已经被取消了,使用Exception取代。

TYPES模块中的常量

types模块里各种各样的常量能够帮助你决定一个对象的类型。在python2里,它包含了代表所有基本数据类型的常量,如dict和int。在python3里,这些常量被取消了,只需使用基础类型的名字来替代。

python2python3
types.UnicodeTypestr
types.StringTypebytes
types.DictTypedict
types.IntTypeint
types.LongTypeint
types.ListTypelist
types.NoneTypetype(None
types.BooleanTypebool
types.BufferTypememoryview
types.ClassTypetype
types.ComplexTypecomplex
types.EllipsisTypetype(Ellipsis)
types.FloatTypefloat
types.ObjectTypeobject
types.NotImplementedTypetype(NotImplemented)
types.SliceTypeslice
types.TupleTypetuple
types.TypeTypetype
types.XRangeTyperange

全局函数ISINSTANCE()

isinstance()函数检查一个对象是否是一个特定类(class)或类型(type)的实例。在python2,可以传递一个由类型构成的元组给isinstance(),如果该对象是元组里的任意一种类型,函数返回True. 在python3,依然可以这样做。

python2python3
isinstance(x, (int, float, int))isinstance(x, (int, float))

ITERTOOLS模块

python2.3引入itertools模块,定义了zip(),map(),filter()的变体,这个变体返回的是迭代器,而非列表。在python3,这些函数返回的本身就是迭代器,所有这些变体函数就取消了。

SYS.EXC_TYPE,SYS.EXC_VALUE,SYS.EXC_TRACEBACK

处理异常的时候,在sys模块里有三个你可以访问的变量:sys.exc_type, sys.exc_value, sys.exc_traceback. python3中这三个变量不再存在,使用sys.exc_info替代。

对元组的列表解析

python2,如果需要编写一个遍历元组的列表解析,不需要在元组值周围加上括号。在python3里,这些括号是必需的。

python2python3
[ i for i in 1, 2][i for i in (1,2)]

元类

在python2里,可以通过在类的声明中定义metaclass参数,或者定义一个特殊的类级别(class-level)__metaclass__属性,来创建元类。python3中,__metaclass__属性被取消了。

python2python3note
class C(metaclass=PapayaMeta): passunchanged 
class Whip: __metaclass__ = PapayMetaclass Whip(metaclass=PapayaMeta): pass 
class C(Whipper, Beater): __metaclass__ = PapayaMetaclass C(Whipper, Beater, metaclass=PapayMeta): pass

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值