Python 3.0 的新特性¶
- 作者:
Guido van Rossum
本文解釋了 Python 3.0 相較於 2.6 的新特性。Python 3.0,也被稱為“Python 3000”或“Py3K”,是第一個有意向後不相容的 Python 版本。Python 3.0 於 2008 年 12 月 3 日釋出。與典型的版本相比,它有更多的更改,並且對所有 Python 使用者來說都更重要。然而,在消化了這些更改之後,你會發現 Python 實際上並沒有改變太多——總的來說,我們主要是在修復眾所周知的煩惱和缺陷,並刪除大量舊的無用程式碼。
本文不試圖提供所有新功能的完整規範,而是試圖給出一個方便的概述。有關完整詳細資訊,您應該參考 Python 3.0 的文件和/或文字中引用的許多 PEP。如果您想了解特定功能的完整實現和設計原理,PEP 通常比常規文件有更多的細節;但請注意,一旦某個功能完全實現,PEP 通常不會保持更新。
由於時間限制,本文件並不像它應該的那樣完整。與新版本一樣,原始碼發行版中的 Misc/NEWS
檔案包含有關所做的每一件小事的豐富詳細資訊。
常見的絆腳石¶
本節列出瞭如果您習慣了 Python 2.5 最容易讓您絆倒的一些更改。
Print 是一個函式¶
print
語句已被 print()
函式取代,該函式帶有關鍵字引數,以取代舊 print
語句的大部分特殊語法 (PEP 3105)。例子
Old: print "The answer is", 2*2
New: print("The answer is", 2*2)
Old: print x, # Trailing comma suppresses newline
New: print(x, end=" ") # Appends a space instead of a newline
Old: print # Prints a newline
New: print() # You must call the function!
Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)
Old: print (x, y) # prints repr((x, y))
New: print((x, y)) # Not the same as print(x, y)!
您還可以自定義專案之間的分隔符,例如
print("There are <", 2**32, "> possibilities!", sep="")
這會產生
There are <4294967296> possibilities!
注意
檢視和迭代器代替列表¶
一些眾所周知的 API 不再返回列表
dict
方法dict.keys()
、dict.items()
和dict.values()
返回“檢視”而不是列表。例如,這不再有效:k = d.keys(); k.sort()
。請使用k = sorted(d)
代替(這在 Python 2.5 中也有效,並且同樣高效)。此外,不再支援
dict.iterkeys()
、dict.iteritems()
和dict.itervalues()
方法。map()
和filter()
返回迭代器。如果您真的需要列表,並且輸入序列的長度都相等,則一個快速的解決方法是將map()
包裝在list()
中,例如list(map(...))
,但更好的解決方法通常是使用列表推導式(特別是當原始程式碼使用lambda
時),或者重寫程式碼使其根本不需要列表。特別棘手的是map()
為了函式副作用而呼叫;正確的轉換是使用常規的for
迴圈(因為建立列表只會浪費)。如果輸入序列的長度不相等,則
map()
將在最短序列終止時停止。為了與 Python 2.x 中的map()
完全相容,還要將序列包裝在itertools.zip_longest()
中,例如map(func, *sequences)
變為list(map(func, itertools.zip_longest(*sequences)))
。range()
現在的行為類似於xrange()
過去的行為,只是它可以處理任意大小的值。後者不再存在。zip()
現在返回一個迭代器。
排序比較¶
Python 3.0 簡化了排序比較的規則
當運算元沒有有意義的自然排序時,排序比較運算子(
<
、<=
、>=
、>
)會引發 TypeError 異常。因此,像1 < ''
、0 > None
或len <= len
這樣的表示式不再有效,例如,None < None
會引發TypeError
而不是返回False
。一個推論是,對異構列表進行排序不再有意義——所有元素都必須彼此可比較。請注意,這不適用於==
和!=
運算子:不同且不可比較型別的物件始終彼此比較不相等。sorted()
和list.sort()
不再接受提供比較函式的 *cmp* 引數。請改用 *key* 引數。注意,*key* 和 *reverse* 引數現在是“僅關鍵字”的引數。cmp()
函式應被視為已刪除,並且不再支援__cmp__()
特殊方法。請將__lt__()
用於排序,將__eq__()
與__hash__()
結合使用,並根據需要使用其他豐富的比較。(如果您真的需要cmp()
功能,則可以使用表示式(a > b) - (a < b)
作為cmp(a, b)
的等效項。)
整數¶
PEP 237:本質上,
long
被重新命名為int
。也就是說,只有一個內建的整數型別,名為int
;但它的行為方式大多與舊的long
型別相同。PEP 238:像
1/2
這樣的表示式返回一個浮點數。使用1//2
來獲得截斷行為。(後一種語法已經存在多年,至少從 Python 2.2 開始就有了。)sys.maxint
常量被移除,因為整數的值不再有限制。然而,sys.maxsize
可以用作大於任何實際列表或字串索引的整數。它符合實現的“自然”整數大小,並且通常與同一平臺上先前版本中的sys.maxint
相同(假設使用相同的構建選項)。長整數的
repr()
不再包含尾部的L
,因此無條件剝離該字元的程式碼將改為截斷最後一位數字。(請改用str()
。)八進位制字面量不再採用
0720
的形式;請改用0o720
。
文字與資料,而非 Unicode 與 8 位¶
你所認為的關於二進位制資料和 Unicode 的一切都已改變。
Python 3.0 使用 _文字_ 和(二進位制)_資料_ 的概念,而不是 Unicode 字串和 8 位字串。所有文字都是 Unicode;然而,_編碼_ 的 Unicode 表示為二進位制資料。用於儲存文字的型別是
str
,用於儲存資料的型別是bytes
。與 2.x 情況的最大區別在於,任何在 Python 3.0 中混合文字和資料的嘗試都會引發TypeError
,而在 Python 2.x 中混合 Unicode 和 8 位字串,如果 8 位字串恰好只包含 7 位 (ASCII) 位元組,則會起作用,但如果它包含非 ASCII 值,則會得到UnicodeDecodeError
。多年來,這種特定於值的行為導致了許多不愉快的局面。由於這種理念的改變,幾乎所有使用 Unicode、編碼或二進位制資料的程式碼都可能需要更改。這種改變是積極的,因為在 2.x 版本中,存在許多與混合編碼和未編碼文字有關的錯誤。為了在 Python 2.x 中做好準備,請開始對所有未編碼文字使用
unicode
,並僅對二進位制或編碼資料使用str
。然後2to3
工具將為你完成大部分工作。你不能再使用
u"..."
字面量表示 Unicode 文字。但是,你必須使用b"..."
字面量表示二進位制資料。由於
str
和bytes
型別不能混合使用,你必須始終在它們之間進行顯式轉換。使用str.encode()
從str
轉到bytes
,使用bytes.decode()
從bytes
轉到str
。你還可以分別使用bytes(s, encoding=...)
和str(b, encoding=...)
。與
str
一樣,bytes
型別是不可變的。有一個單獨的 _可變_ 型別用於儲存緩衝的二進位制資料,bytearray
。幾乎所有接受bytes
的 API 也接受bytearray
。可變 API 基於collections.MutableSequence
。原始字串字面量中的所有反斜槓都按字面意思解釋。這意味著原始字串中的
'\U'
和'\u'
轉義不會被特殊處理。例如,r'\u20ac'
在 Python 3.0 中是一個包含 6 個字元的字串,而在 2.6 中,ur'\u20ac'
是單個“歐元”字元。(當然,此更改僅影響原始字串字面量;歐元字元在 Python 3.0 中是'\u20ac'
。)內建的
basestring
抽象型別已被移除。請改用str
。str
和bytes
型別沒有足夠多的共同功能來保證使用共享的基類。2to3
工具(見下文)將每個basestring
的出現替換為str
。作為文字檔案開啟的檔案(仍然是
open()
的預設模式)始終使用編碼在字串(在記憶體中)和位元組(在磁碟上)之間進行對映。二進位制檔案(在模式引數中使用b
開啟)始終在記憶體中使用位元組。這意味著,如果使用不正確的模式或編碼開啟檔案,I/O 很可能會大聲失敗,而不是默默地產生不正確的資料。這也意味著,即使是 Unix 使用者也必須在開啟檔案時指定正確的模式(文字或二進位制)。存在一個平臺相關的預設編碼,在 Unix 平臺上可以使用LANG
環境變數進行設定(有時也可以使用其他一些平臺特定的區域設定相關的環境變數)。在許多情況下,但並非所有情況下,系統預設值都是 UTF-8;你不應依賴此預設值。任何讀取或寫入純 ASCII 文字之外的內容的應用程式都應該有一種覆蓋編碼的方法。不再需要在codecs
模組中使用編碼感知流。sys.stdin
、sys.stdout
和sys.stderr
的初始值現在都是僅限 Unicode 的文字檔案(即,它們是io.TextIOBase
的例項)。要使用這些流讀取和寫入位元組資料,你需要使用它們的io.TextIOBase.buffer
屬性。檔名以(Unicode)字串的形式傳遞給 API 並從 API 返回。這可能會帶來平臺特定的問題,因為在某些平臺上,檔名是任意的位元組字串。(另一方面,在 Windows 上,檔名以 Unicode 的形式原生儲存。)作為一種變通方法,大多數接受檔名的 API(例如
open()
和os
模組中的許多函式)也接受bytes
物件以及字串,並且一些 API 有方法請求返回bytes
值。因此,如果引數是bytes
例項,則os.listdir()
返回一個bytes
例項列表,而os.getcwdb()
返回當前工作目錄作為bytes
例項。請注意,當os.listdir()
返回字串列表時,無法正確解碼的檔名會被省略,而不是引發UnicodeError
。當系統提供的位元組無法使用預設編碼解釋時,某些系統 API(如
os.environ
和sys.argv
)也可能會出現問題。設定LANG
變數並重新執行程式可能是最好的方法。PEP 3138: 字串的
repr()
不再轉義非 ASCII 字元。但是,它仍然會轉義控制字元和 Unicode 標準中具有不可列印狀態的程式碼點。PEP 3120: 預設的原始碼編碼現在是 UTF-8。
PEP 3131: 現在識別符號中允許使用非 ASCII 字母。(但是,標準庫仍然僅限 ASCII,註釋中的貢獻者姓名除外。)
StringIO
和cStringIO
模組已刪除。請改為匯入io
模組,並分別使用io.StringIO
或io.BytesIO
來處理文字和資料。另請參閱為 Python 3.0 更新的 Unicode HOWTO。
語法更改概述¶
本節簡要概述 Python 3.0 中的每個語法更改。
新語法¶
PEP 3107: 函式引數和返回值註解。這提供了一種標準化方法來註解函式的引數和返回值。這些註解沒有附加的語義,只是可以使用
__annotations__
屬性在執行時進行內省。目的是鼓勵透過元類、裝飾器或框架進行實驗。PEP 3102: 僅限關鍵字的引數。引數列表中出現在
*args
之後的命名引數必須在呼叫時使用關鍵字語法指定。你也可以在引數列表中使用裸*
來表示你不接受可變長度的引數列表,但你有僅限關鍵字的引數。在類定義中,基本類列表之後允許使用關鍵字引數。這被用於指定元類的新約定(請參閱下一節),但只要元類支援,它也可以用於其他目的。
PEP 3104:
nonlocal
語句。使用nonlocal x
,你現在可以直接賦值給外部(但非全域性)作用域中的變數。nonlocal
是一個新的保留字。PEP 3132: 擴充套件的可迭代解包。你現在可以編寫諸如
a, b, *rest = some_sequence
之類的程式碼。甚至*rest, a = stuff
。rest
物件始終是一個(可能為空)列表;右側可以是任何可迭代物件。示例(a, *rest, b) = range(5)
這將 a 設定為
0
,b 設定為4
,rest 設定為[1, 2, 3]
。字典推導式:
{k: v for k, v in stuff}
與dict(stuff)
的含義相同,但更靈活。(這是 PEP 274 證明是正確的。 :-))集合字面量,例如
{1, 2}
。請注意,{}
是一個空字典;對於空集合,請使用set()
。也支援集合推導式;例如,{x for x in stuff}
與set(stuff)
的含義相同,但更靈活。新的八進位制字面量,例如
0o720
(在 2.6 中已經存在)。舊的八進位制字面量 (0720
) 已刪除。新的二進位制字面量,例如
0b1010
(在 2.6 中已經存在),並且有一個新的對應的內建函式bin()
。位元組字面量以引導
b
或B
引入,並且有一個新的對應的內建函式bytes()
。
更改的語法¶
PEP 3109 和 PEP 3134: 新的
raise
語句語法:raise [expr [from expr]]
。請參閱下文。as
和with
現在是保留字。(實際上是從 2.6 開始。)True
、False
和None
是保留字。(2.6 已經部分強制執行了對None
的限制。)PEP 3115: 新的元類語法。而不是
class C: __metaclass__ = M ...
你現在必須使用
class C(metaclass=M): ...
不再支援模組全域性
__metaclass__
變數。(它是一個柺杖,用於使在不從object
派生每個類的情況下,更容易預設使用新式類。)列表推導式不再支援
[... for var in item1, item2, ...]
這種語法形式。請改用[... for var in (item1, item2, ...)]
。 另外請注意,列表推導式具有不同的語義:它們更接近於list()
建構函式內部生成器表示式的語法糖,特別是迴圈控制變數不再洩露到周圍的作用域中。省略號 (
...
) 可以用作任何位置的原子表示式。(以前只允許在切片中使用。)此外,它現在必須拼寫為...
。(以前也可以拼寫為. . .
,這只是語法上的一個偶然情況。)
已移除的語法¶
PEP 3113:元組引數解包已移除。您不能再編寫
def foo(a, (b, c)): ...
。請改用def foo(a, b_c): b, c = b_c
。移除了反引號(請改用
repr()
)。移除了
<>
(請改用!=
)。移除了關鍵字:
exec()
不再是關鍵字;它仍然是一個函式。(幸運的是,在 2.x 中也接受函式語法。)另請注意,exec()
不再接受流引數;您可以使用exec(f.read())
來代替exec(f)
。整數文字不再支援尾隨的
l
或L
。字串文字不再支援前導的
u
或U
。相對匯入唯一可接受的語法是
from .[模組] import 名稱
。所有不以.
開頭的import
形式都被解釋為絕對匯入。(PEP 328)經典類已移除。
Python 2.6 中已存在的更改¶
由於許多使用者可能直接從 Python 2.5 跳轉到 Python 3.0,因此本節提醒讀者注意最初為 Python 3.0 設計但已向後移植到 Python 2.6 的新功能。有關更詳細的描述,請查閱 Python 2.6 中的新增功能 中的相應章節。
PEP 343: ‘with’ 語句。
with
語句現在是標準功能,不再需要從__future__
匯入。另請檢視 編寫上下文管理器 和 contextlib 模組。PEP 366: 從主模組顯式相對匯入。這增強了當引用的模組位於包中時
-m
選項的實用性。PEP 3101: 高階字串格式化。注意:2.6 的描述中提到了 8 位字串和 Unicode 字串的
format()
方法。在 3.0 中,只有str
型別(支援 Unicode 的文字字串)支援此方法;bytes
型別不支援。計劃最終使其成為字串格式化的唯一 API,並在 Python 3.1 中開始棄用%
運算子。PEP 3105: 將 print 作為函式。這現在是一個標準功能,不再需要從
__future__
匯入。上面已提供了更多詳細資訊。PEP 3110: 異常處理變更。
except
excas
var 語法現在是標準的,不再支援except
exc, var。(當然,as
var 部分仍然是可選的。)PEP 3112: 位元組文字。
b"..."
字串文字表示法(及其變體,如b'...'
、b"""..."""
和br"..."
)現在生成bytes
型別的文字。PEP 3116: 新 I/O 庫。
io
模組現在是進行檔案 I/O 的標準方式。內建的open()
函式現在是io.open()
的別名,並具有附加的關鍵字引數 encoding、errors、newline 和 closefd。另請注意,無效的 mode 引數現在會引發ValueError
,而不是IOError
。可以透過f.buffer
訪問文字檔案物件下方的二進位制檔案物件(但請注意,文字物件會維護自身的緩衝區,以便加快編碼和解碼操作)。PEP 3118: 修訂的緩衝協議。舊的內建
buffer()
現在真的消失了;新的內建memoryview()
提供了(大部分)類似的功能。PEP 3119:抽象基類。
abc
模組和collections
模組中定義的 ABC 在該語言中扮演著更為重要的角色,並且諸如dict
和list
等內建集合型別分別符合collections.MutableMapping
和collections.MutableSequence
ABC。PEP 3127:整數文字支援和語法。 如上所述,新的八進位制文字表示法是唯一受支援的表示法,並且已添加了二進位制文字。
PEP 3141:數字的型別層次結構。
numbers
模組是 ABC 的另一個新用法,它定義了 Python 的“數字塔”。 另請注意實現numbers.Rational
的新fractions
模組。
庫的更改¶
由於時間限制,本文件並未詳盡涵蓋標準庫的非常廣泛的更改。PEP 3108 是庫的主要更改的參考。以下是簡要回顧
許多舊模組已被刪除。 一些模組,例如
gopherlib
(不再使用)和md5
(已由hashlib
替換),已被 PEP 4 棄用。 其他模組由於取消了對各種平臺(例如 Irix,BeOS 和 Mac OS 9)的支援而被刪除(請參閱 PEP 11)。 一些模組也由於缺乏使用或存在更好的替代方案而在 Python 3.0 中被選中刪除。 有關詳盡列表,請參閱 PEP 3108。bsddb3
包已被刪除,因為它在核心標準庫中的存在已被證明是核心開發人員的特殊負擔,原因是測試不穩定以及 Berkeley DB 的釋出計劃。 但是,該軟體包在 https://www.jcea.es/programacion/pybsddb.htm 上得到了活躍且良好的維護。一些模組由於其舊名稱違反了 PEP 8,或者出於各種其他原因而被重新命名。 這是列表
舊名稱
新名稱
_winreg
winreg
ConfigParser
configparser
copy_reg
copyreg
Queue
queue
SocketServer
socketserver
markupbase
_markupbase
repr
reprlib
test.test_support
test.support
Python 2.x 中的一種常見模式是使用純 Python 實現模組的一個版本,並使用 C 擴充套件來實現可選的加速版本; 例如,
pickle
和cPickle
。 這將匯入加速版本並回退到這些模組的每個使用者的純 Python 版本的負擔。 在 Python 3.0 中,加速版本被認為是純 Python 版本的實現細節。 使用者應始終匯入標準版本,該版本嘗試匯入加速版本並回退到純 Python 版本。pickle
/cPickle
對已受到這種處理。profile
模組在 3.1 的列表中。StringIO
模組已轉換為io
模組中的一個類。一些相關的模組已分組到包中,並且通常簡化了子模組名稱。 產生的新包是
dbm
(anydbm
,dbhash
,dbm
,dumbdbm
,gdbm
,whichdb
)。html
(HTMLParser
,htmlentitydefs
)。http
(httplib
,BaseHTTPServer
,CGIHTTPServer
,SimpleHTTPServer
,Cookie
,cookielib
)。tkinter
(所有與Tkinter
相關的模組,除了turtle
)。turtle
的目標受眾實際上並不關心tkinter
。 另請注意,自 Python 2.6 起,turtle
的功能已大大增強。urllib
(urllib
,urllib2
,urlparse
,robotparse
)。xmlrpc
(xmlrpclib
,DocXMLRPCServer
,SimpleXMLRPCServer
)。
對標準庫模組的其他一些更改,未在 PEP 3108 中涵蓋
已刪除
sets
。 請使用內建的set()
類。清理
sys
模組:刪除了sys.exitfunc()
,sys.exc_clear()
,sys.exc_type
,sys.exc_value
,sys.exc_traceback
。 (請注意,sys.last_type
等仍然存在。)清理
array.array
型別:read()
和write()
方法已移除;請改用fromfile()
和tofile()
。此外,array 的'c'
型別程式碼也已移除 – 請使用'b'
表示位元組,或使用'u'
表示 Unicode 字元。清理
operator
模組:移除了sequenceIncludes()
和isCallable()
。清理
thread
模組:acquire_lock()
和release_lock()
已移除;請改用acquire()
和release()
。清理
random
模組:移除了jumpahead()
API。new
模組已移除。函式
os.tmpnam()
、os.tempnam()
和os.tmpfile()
已移除,請改用tempfile
模組。tokenize
模組已更改為使用位元組工作。現在的主要入口點是tokenize.tokenize()
,而不是 generate_tokens。string.letters
及其朋友(string.lowercase
和string.uppercase
)已移除。請改用string.ascii_letters
等。(移除的原因是string.letters
及其朋友具有特定於語言環境的行為,對於這種具有吸引力的全域性“常量”來說,這不是一個好主意。)將模組
__builtin__
重新命名為builtins
(刪除了下劃線,添加了 ‘s’)。在大多數全域性名稱空間中找到的__builtins__
變數保持不變。要修改內建物件,您應該使用builtins
,而不是__builtins__
!
PEP 3101:一種新的字串格式化方法¶
一個新的內建字串格式化作業系統取代了
%
字串格式化運算子。(但是,仍然支援%
運算子;它將在 Python 3.1 中被棄用,並在以後的某個時間從語言中刪除。)請閱讀 PEP 3101 以獲取完整資訊。
異常的更改¶
引發和捕獲異常的 API 已被清理,並添加了新的強大功能
PEP 352:所有異常都必須(直接或間接)派生自
BaseException
。這是異常層次結構的根。這並非新的建議,但繼承自BaseException
的要求是新的。(Python 2.6 仍然允許引發經典類,並且對您可以捕獲的內容沒有任何限制。)因此,字串異常最終真正徹底地消亡了。幾乎所有異常實際上都應該派生自
Exception
;BaseException
應該僅用作應該僅在頂層處理的異常的基類,例如SystemExit
或KeyboardInterrupt
。處理除後一類之外的所有異常的推薦用法是使用except
Exception
。StandardError
已移除。異常不再表現為序列。請改用
args
屬性。PEP 3109:引發異常。現在您必須使用
raise Exception(args)
,而不是raise Exception, args
。此外,您不能再顯式指定回溯;相反,如果您必須這樣做,您可以直接分配給__traceback__
屬性(見下文)。PEP 3110:捕獲異常。現在您必須使用
except SomeException as variable
,而不是except SomeException, variable
。此外,當except
塊離開時,variable 會被顯式刪除。PEP 3134:異常連結。有兩種情況:隱式連結和顯式連結。當在
except
或finally
處理程式塊中引發異常時,會發生隱式連結。這通常是由於處理程式塊中的錯誤導致的;我們稱之為次級異常。在這種情況下,原始異常(正在處理的異常)將作為次級異常的__context__
屬性儲存。使用以下語法呼叫顯式連結raise SecondaryException() from primary_exception
(其中 *primary_exception* 是產生異常物件的任何表示式,可能是之前捕獲的異常)。在這種情況下,主異常儲存在次級異常的
__cause__
屬性上。當發生未處理的異常時列印的回溯會遍歷__cause__
和__context__
屬性的鏈,併為鏈的每個元件列印單獨的回溯,主異常位於頂部。(Java 使用者可能會認識到此行為。)PEP 3134:異常物件現在將其回溯儲存為
__traceback__
屬性。這意味著異常物件現在包含與異常相關的所有資訊,並且使用sys.exc_info()
的理由更少了(儘管後者並未被移除)。當 Windows 無法載入擴充套件模組時,改進了一些異常訊息。例如,
錯誤程式碼 193
現在是%1 不是有效的 Win32 應用程式
。字串現在處理非英語語言環境。
其他雜項更改¶
運算子和特殊方法¶
!=
現在返回==
的相反結果,除非==
返回NotImplemented
。“未繫結方法”的概念已從語言中刪除。當將方法作為類屬性引用時,現在會得到一個普通的函式物件。
__getslice__()
、__setslice__()
和__delslice__()
已被移除。語法a[i:j]
現在轉換為a.__getitem__(slice(i, j))
(或者,當用作賦值或刪除目標時,分別轉換為__setitem__()
或__delitem__()
)。PEP 3114:標準的
next()
方法已重新命名為__next__()
。移除了
__oct__()
和__hex__()
特殊方法 ——oct()
和hex()
現在使用__index__()
將引數轉換為整數。移除了對
__members__
和__methods__
的支援。名為
func_X
的函式屬性已重新命名為使用__X__
形式,從而在函式屬性名稱空間中為使用者定義的屬性釋放這些名稱。也就是說,func_closure
、func_code
、func_defaults
、func_dict
、func_doc
、func_globals
、func_name
分別重新命名為__closure__
、__code__
、__defaults__
、__dict__
、__doc__
、__globals__
、__name__
。__nonzero__()
現在是__bool__()
。
內建函式¶
PEP 3135:新的
super()
。現在可以不帶引數呼叫super()
,並且(假設這是在class
語句中定義的常規例項方法)會自動選擇正確的類和例項。帶引數時,super()
的行為不變。PEP 3111:
raw_input()
已重新命名為input()
。也就是說,新的input()
函式從sys.stdin
讀取一行,並刪除末尾的換行符後返回。如果輸入過早終止,則會引發EOFError
。要獲得舊的input()
行為,請使用eval(input())
。添加了一個新的內建函式
next()
,用於呼叫物件上的__next__()
方法。round()
函式的舍入策略和返回型別已更改。精確的中間情況現在舍入到最接近的偶數結果,而不是遠離零。(例如,round(2.5)
現在返回2
而不是3
。)round(x[, n])
現在委託給x.__round__([n])
而不是總是返回浮點數。當使用單個引數呼叫時,它通常返回一個整數;當使用兩個引數呼叫時,它返回與x
相同型別的值。將
intern()
移到sys.intern()
。已移除:
apply()
。使用f(*args)
代替apply(f, args)
。移除了
callable()
。可以使用isinstance(f, collections.Callable)
代替callable(f)
。operator.isCallable()
函式也已消失。移除了
coerce()
。既然經典類已經消失,此函式不再有作用。移除了
execfile()
。使用exec(open(fn).read())
代替execfile(fn)
。移除了
reduce()
。如果確實需要,請使用functools.reduce()
;但是,99% 的時間裡,顯式的for
迴圈更具可讀性。移除了
reload()
。請使用imp.reload()
。已移除。
dict.has_key()
– 請改用in
運算子。
構建和 C API 更改¶
由於時間限制,這裡僅列出 C API 更改的非常不完整的列表。
刪除了對多個平臺的支援,包括但不限於 Mac OS 9、BeOS、RISCOS、Irix 和 Tru64。
PEP 3118:新的緩衝區 API。
PEP 3121:擴充套件模組初始化和最終化。
PEP 3123:使
PyObject_HEAD
符合標準 C 規範。不再支援 C API 的受限執行。
PyNumber_Coerce()
、PyNumber_CoerceEx()
、PyMember_Get()
和PyMember_Set()
C API 已被移除。新的 C API
PyImport_ImportModuleNoBlock()
,其功能類似於PyImport_ImportModule()
,但不會阻塞匯入鎖(而是返回錯誤)。重新命名了布林轉換的 C 級槽和方法:
nb_nonzero
現在是nb_bool
。從 C API 中移除了
METH_OLDARGS
和WITH_CYCLE_GC
。
效能¶
3.0 版本通用化的最終結果是,Python 3.0 執行 pystone 基準測試比 Python 2.5 慢約 10%。最大的原因很可能是移除了對小整數的特殊處理。仍然有改進的空間,但這將在 3.0 釋出後進行!
移植到 Python 3.0¶
對於將現有的 Python 2.5 或 2.6 原始碼移植到 Python 3.0,最佳策略如下:
(前提條件:)從出色的測試覆蓋率開始。
移植到 Python 2.6。這應該不會比從 Python 2.x 到 Python 2.(x+1) 的平均移植工作量更多。確保所有測試都透過。
(仍然使用 2.6:)開啟
-3
命令列開關。這將啟用有關 3.0 中將刪除(或更改)的功能的警告。再次執行您的測試套件,並修復您收到警告的程式碼,直到沒有剩餘警告,並且所有測試仍然透過。在您的原始碼樹上執行
2to3
原始碼到原始碼轉換器。在 Python 3.0 下執行轉換後的結果。手動修復任何剩餘的問題,直到所有測試再次透過。
不建議嘗試編寫在 Python 2.6 和 3.0 下都能不變地執行的原始碼;您必須使用非常扭曲的編碼風格,例如避免使用 print
語句、元類等等。如果您正在維護一個需要同時支援 Python 2.6 和 Python 3.0 的庫,最好的方法是透過編輯 2.6 版本的原始碼並再次執行 2to3
轉換器來修改上面的步驟 3,而不是編輯 3.0 版本的原始碼。
有關將 C 擴充套件移植到 Python 3.0 的資訊,請參閱 將擴充套件模組移植到 Python 3。