幾乎全部的python2程序都須要一些修改才能正常的運行在python3的環境下。爲了簡化這個轉換過程,Python3自帶了一個2to3的實用腳本.這個腳本會將python2程序源文件做爲輸入,而後自動轉換到python3.但並非全部內容均可以自動轉換。python
print語句
python2中print是一個語句,不論想輸出什麼,直接放到print關鍵字後面便可。python3裏,print()是一個函數,像其餘函數同樣,print()須要你將要輸出的東西做爲參數傳給它。性能優化
python2 | python3 | 備註 |
---|---|---|
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 |