python2 与 python3的区别

2018/10/11 16:31
阅读数 194


python2 与 python3的区别

 

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

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

python2中有两种字符串类型:Unicode字符串和非Unicode字符串。Python3中只有一种类型:Unicode字符串。
python2    python3    备注
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中的长整型类似。
python2    python3    备注
x = 1000000000000L     x = 1000000000000     python2中的十进制长整型在python3中被替换为十进制普通整数
x = 0xFFFFFFFFFFFFL     x = 0xFFFFFFFFFFFF     python2里的十六进制长整型在python3里被替换为十六进制的普通整数
long(x)     int(x)     python3没有long()
type(x) is long     type(x) is int     python3用int判断是否为整型
isinstance(x, long)     isinstance(x, int)     int检查整数类型
<>比较运算符

Python2支持<>作为!=的同义词, python3只支持!=, 不再支持<>
字典类方法HAS_KEY()

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

在python2里,许多字典类方法的返回值是列表。最常用方法有keys, items和values。python3,所有以上方法的返回值改为动态试图。在一些上下文环境里,这种改变不会产生影响。如果这些方法的返回值被立即传递给另外一个函数,而且那个函数会遍历整个序列,那么以上方法的返回值是列表或视图并不会产生什么不同。如果你期望获得一个被独立寻址元素的列表,那么python3的这些改变将会使你的代码卡住,因为视图不支持索引。
python2    python3    备注
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
python2    python3    备注
import httplib     import http.client     http.client模块实现一个底层的库,可以用来请求和解析http
import cookie     import http.cookies     http.cookie提供一个pythonic接口进行cookies操作
import cookielib     import http.cookiejar     http.cookiejar可以操作cookies文件
import BaseHTTPServer import SimpleHTTPServer import CGIHttpServer     import http.server     http.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包中合适的模块。
python2    python3    备注
import dbm     import dbm.ndbm     
import gdbm     import dbm.gnu     
import dbhash     import dbm.bad     
import dumbdbm     import dbm.dumb     
import anydbm import whichdb     import dbm     

XMLRPC

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

其他模块
Python2    python3    备注
try: import cStringIO as StringIO except ImportError: import STringIO     import io     
try: import cPickle as pickle except ImportError: import pickle     import pickle     
import builtin     import builtins     
import copy_reg     import copyreg     
import Queue     import queue     
import SocketServer     import socketserver     
import ConfigParser     import configparser     
import repr     import reprlib     
import commands     import subprocess     

包内的相对导入

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

迭代器方法NEXT()

python2里,迭代器有一个next()方法,用来返回序列的下一项。在python3里同样成立。但是有一个新的全局的函数next(),它使用一个迭代器作为参数。
python2    python3    备注
anIterator.next()     next(anIterator)     
a_function_that_returns_an_iterator().next()     next(a_function_that_returns_an_iterator())     
class A: def next(self): pass     class A : def next(self): pass     
class A: def next(self, x, y): pass     no 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()函数返回一个迭代器,不再是列表。
python2    python3    备注
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中返回一个列表。
python2    python3    备注
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模块里。
python2    python3    备注
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()函数不再存在;必须使用星号标记。
python2    python3    备注
apply(a_function, a_list_of_args     a_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模块里。
python2    python3    备注
intern(aString)     sys.intern(aString)     --------

EXEC

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

execfile

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

REPR

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

TRYEXCEPT语句

python2到python3,捕获异常的语法有些变化。
Python2    Python3    备注
try: import mymodule except ImportError, e pass     try: import mymodule except ImportError as e: pass     
try: import mymodule except (RuntimeError, ImportError), e pass     try: import mymodule except(RuntimeError, ImportError) as e: pass     
try: import mymodule except ImportError: pass     no change     
try: import mymodule except: pass     no change     

RAISE

python3里,抛出自定义异常的语法有细微的变化。
python2    python3    备注
raise MyException     unchanged     
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中,这一功能仍然可用,但语法有一点不同。
python2    python3    备注
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()不再存在。

 
python2    python3    备注
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替代了他们。
python2    python3    备注
raw_input()     input     input替代了raw_input
raw_input('prompt')     input('prompt')     python3仍然支持提示符参数
input()     eval(input))     
函数属性FUNC_*

python2,函数的代码可用访问到函数本身的特殊属性。python3为了一致性,这些特殊属性被重命名了。
python2    python3    备注
a_function.func_name     a_function.__name__     __name__属性包含了函数的名字
a_function.func_doc     a_function.__doc__     __doc__包含了函数源代码定义的文档字符串
a_function.func_defaults     a_function.__defaults__     是一个保存参数默认值的元组
a_function.func_dict     a_function.__dict__     __dict__属性是一个支持任意函数属性的名字空间
a_function.func_closure     a_function.__closure__     __closure__属性是由cell对象组成的元组,包含了函数对自由变量的绑定
a_function.func_globals     a_function.__globals__     是对模块全局名字空间的引用
a_function.func_code     a_function.__code__     是一个代码对象,表示编译后的函数体
I/O方法XREADLINES()

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

在python2中,可以定义匿名函数lambda函数,通过指定作为参数的元组的元素个数,使这个函数实际上能够接收多个参数。python2的解释器把这个元组"解开“成命名参数,然后可以在lambda函数里引用它们。在python3中仍然可以传递一个元组为lambda函数的参数。但是python解释器不会把它当成解析成命名参数。需要通过位置索引来引用每个参数。
python2    python3    备注
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 + z     lambda x_y_z: x_y_z[0] + x_y_z[1][0]+ x_y_z[1][1]     注3
lambda x,y,z: x+y+z     unchanged     注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里,这些属性被重命名,以遵循其他属性的命名约定。
python2    python3
aClassInstance.aClassMethod.im_func     aClassInstance.aClassMethod.__func__
aClassInstance.aClassMethod.im_self     aClassInstance.aClassMethod.__self__
aClassInstance.aClassMethod.im_class     aClassInstance.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,定义八进制数的语法有轻微的改变
python2    python3
x= 0755     x = 0o755
SYS.MAXINT

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

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

在python2,zip()可以使用任意多个序列作为参数,它返回一个由元组构成的列表。第一个元组包含了每个序列的第一个元素,第二个元组包含了每个序列的第二个元素,依次递推。在python3中返回一个迭代器,而非列表。
python2    python3    note
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里,这些常量被取消了,只需使用基础类型的名字来替代。
python2    python3
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
全局函数ISINSTANCE()

isinstance()函数检查一个对象是否是一个特定类(class)或类型(type)的实例。在python2,可以传递一个由类型构成的元组给isinstance(),如果该对象是元组里的任意一种类型,函数返回True. 在python3,依然可以这样做。
python2    python3
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里,这些括号是必需的。
python2    python3
[ i for i in 1, 2]     [i for i in (1,2)]
元类

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

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

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

python2中有两种字符串类型:Unicode字符串和非Unicode字符串。Python3中只有一种类型:Unicode字符串。
python2    python3    备注
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中的长整型类似。
python2    python3    备注
x = 1000000000000L     x = 1000000000000     python2中的十进制长整型在python3中被替换为十进制普通整数
x = 0xFFFFFFFFFFFFL     x = 0xFFFFFFFFFFFF     python2里的十六进制长整型在python3里被替换为十六进制的普通整数
long(x)     int(x)     python3没有long()
type(x) is long     type(x) is int     python3用int判断是否为整型
isinstance(x, long)     isinstance(x, int)     int检查整数类型
<>比较运算符

Python2支持<>作为!=的同义词, python3只支持!=, 不再支持<>
字典类方法HAS_KEY()

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

在python2里,许多字典类方法的返回值是列表。最常用方法有keys, items和values。python3,所有以上方法的返回值改为动态试图。在一些上下文环境里,这种改变不会产生影响。如果这些方法的返回值被立即传递给另外一个函数,而且那个函数会遍历整个序列,那么以上方法的返回值是列表或视图并不会产生什么不同。如果你期望获得一个被独立寻址元素的列表,那么python3的这些改变将会使你的代码卡住,因为视图不支持索引。
python2    python3    备注
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
python2    python3    备注
import httplib     import http.client     http.client模块实现一个底层的库,可以用来请求和解析http
import cookie     import http.cookies     http.cookie提供一个pythonic接口进行cookies操作
import cookielib     import http.cookiejar     http.cookiejar可以操作cookies文件
import BaseHTTPServer import SimpleHTTPServer import CGIHttpServer     import http.server     http.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包中合适的模块。
python2    python3    备注
import dbm     import dbm.ndbm     
import gdbm     import dbm.gnu     
import dbhash     import dbm.bad     
import dumbdbm     import dbm.dumb     
import anydbm import whichdb     import dbm     

XMLRPC

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

其他模块
Python2    python3    备注
try: import cStringIO as StringIO except ImportError: import STringIO     import io     
try: import cPickle as pickle except ImportError: import pickle     import pickle     
import builtin     import builtins     
import copy_reg     import copyreg     
import Queue     import queue     
import SocketServer     import socketserver     
import ConfigParser     import configparser     
import repr     import reprlib     
import commands     import subprocess     

包内的相对导入

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

迭代器方法NEXT()

python2里,迭代器有一个next()方法,用来返回序列的下一项。在python3里同样成立。但是有一个新的全局的函数next(),它使用一个迭代器作为参数。
python2    python3    备注
anIterator.next()     next(anIterator)     
a_function_that_returns_an_iterator().next()     next(a_function_that_returns_an_iterator())     
class A: def next(self): pass     class A : def next(self): pass     
class A: def next(self, x, y): pass     no 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()函数返回一个迭代器,不再是列表。
python2    python3    备注
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中返回一个列表。
python2    python3    备注
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模块里。
python2    python3    备注
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()函数不再存在;必须使用星号标记。
python2    python3    备注
apply(a_function, a_list_of_args     a_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模块里。
python2    python3    备注
intern(aString)     sys.intern(aString)     --------

EXEC

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

execfile

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

REPR

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

TRYEXCEPT语句

python2到python3,捕获异常的语法有些变化。
Python2    Python3    备注
try: import mymodule except ImportError, e pass     try: import mymodule except ImportError as e: pass     
try: import mymodule except (RuntimeError, ImportError), e pass     try: import mymodule except(RuntimeError, ImportError) as e: pass     
try: import mymodule except ImportError: pass     no change     
try: import mymodule except: pass     no change     

RAISE

python3里,抛出自定义异常的语法有细微的变化。
python2    python3    备注
raise MyException     unchanged     
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中,这一功能仍然可用,但语法有一点不同。
python2    python3    备注
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()不再存在。

 
python2    python3    备注
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替代了他们。
python2    python3    备注
raw_input()     input     input替代了raw_input
raw_input('prompt')     input('prompt')     python3仍然支持提示符参数
input()     eval(input))     
函数属性FUNC_*

python2,函数的代码可用访问到函数本身的特殊属性。python3为了一致性,这些特殊属性被重命名了。
python2    python3    备注
a_function.func_name     a_function.__name__     __name__属性包含了函数的名字
a_function.func_doc     a_function.__doc__     __doc__包含了函数源代码定义的文档字符串
a_function.func_defaults     a_function.__defaults__     是一个保存参数默认值的元组
a_function.func_dict     a_function.__dict__     __dict__属性是一个支持任意函数属性的名字空间
a_function.func_closure     a_function.__closure__     __closure__属性是由cell对象组成的元组,包含了函数对自由变量的绑定
a_function.func_globals     a_function.__globals__     是对模块全局名字空间的引用
a_function.func_code     a_function.__code__     是一个代码对象,表示编译后的函数体
I/O方法XREADLINES()

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

在python2中,可以定义匿名函数lambda函数,通过指定作为参数的元组的元素个数,使这个函数实际上能够接收多个参数。python2的解释器把这个元组"解开“成命名参数,然后可以在lambda函数里引用它们。在python3中仍然可以传递一个元组为lambda函数的参数。但是python解释器不会把它当成解析成命名参数。需要通过位置索引来引用每个参数。
python2    python3    备注
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 + z     lambda x_y_z: x_y_z[0] + x_y_z[1][0]+ x_y_z[1][1]     注3
lambda x,y,z: x+y+z     unchanged     注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里,这些属性被重命名,以遵循其他属性的命名约定。
python2    python3
aClassInstance.aClassMethod.im_func     aClassInstance.aClassMethod.__func__
aClassInstance.aClassMethod.im_self     aClassInstance.aClassMethod.__self__
aClassInstance.aClassMethod.im_class     aClassInstance.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,定义八进制数的语法有轻微的改变
python2    python3
x= 0755     x = 0o755
SYS.MAXINT

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

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

在python2,zip()可以使用任意多个序列作为参数,它返回一个由元组构成的列表。第一个元组包含了每个序列的第一个元素,第二个元组包含了每个序列的第二个元素,依次递推。在python3中返回一个迭代器,而非列表。
python2    python3    note
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里,这些常量被取消了,只需使用基础类型的名字来替代。
python2    python3
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
全局函数ISINSTANCE()

isinstance()函数检查一个对象是否是一个特定类(class)或类型(type)的实例。在python2,可以传递一个由类型构成的元组给isinstance(),如果该对象是元组里的任意一种类型,函数返回True. 在python3,依然可以这样做。
python2    python3
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里,这些括号是必需的。
python2    python3
[ i for i in 1, 2]     [i for i in (1,2)]
元类

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

展开阅读全文
加载中

作者的其它热门文章

打赏
0
1 收藏
分享
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部
返回顶部
顶部