python2 與 python3的區別

幾乎全部的python2程序都須要一些修改才能正常的運行在python3的環境下。爲了簡化這個轉換過程,Python3自帶了一個2to3的實用腳本.這個腳本會將python2程序源文件做爲輸入,而後自動轉換到python3.但並非全部內容均可以自動轉換。python

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()函數便可完成全部的功能。cookie

LONG長整型

python2有非浮 點數準備的int和long類型。int類型最大值不能超過sys.maxint,並且這個最大值是平臺相關的。能夠經過在數字的末尾附上一個L來定義長 整型,顯然,它比int類型表示的數字範圍更大。在python3裏,只有一種整數類型int,大多數狀況下,和python2中的長整型相似。app

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只支持!=, 再也不支持<>socket

字典類方法HAS_KEY()

Python2中,字典對象has_key()方法測試字典是否包含指定的鍵。python3再也不支持這個方法,須要使用in.函數

返回列表的字典類方法

在python2裏, 許多字典類方法的返回值是列表。最經常使用方法有keys, items和values。python3,全部以上方法的返回值改成動態試圖。在一些上下文環境裏,這種改變不會產生影響。若是這些方法的返回值被當即 傳遞給另一個函數,並且那個函數會遍歷整個序列,那麼以上方法的返回值是列表或視圖並不會產生什麼不一樣。若是你指望得到一個被獨立尋址元素的列表,那麼 python3的這些改變將會使你的代碼卡住,由於視圖不支持索引。post

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
相關文章
相關標籤/搜索