Python 3.3 的新特性¶
本文介紹了 Python 3.3 相對於 3.2 的新特性。Python 3.3 於 2012 年 9 月 29 日釋出。有關完整詳細資訊,請參閱變更日誌。
另請參閱
PEP 398 - Python 3.3 釋出時間表
摘要 – 釋出亮點¶
新的語法特性
新的庫模組
faulthandler
(有助於除錯底層崩潰)ipaddress
(表示 IP 地址和掩碼的高階物件)lzma
(使用 XZ / LZMA 演算法壓縮資料)unittest.mock
(用模擬物件替換被測系統的一部分)
新的內建特性
重構的 I/O 異常層次結構。
實現改進
更緊湊的 unicode 字串。
更緊湊的 屬性字典。
顯著改進的庫模組
安全改進
預設情況下啟用雜湊隨機化。
請繼續閱讀以獲取面向使用者的更改的完整列表。
PEP 405: 虛擬環境¶
虛擬環境有助於建立單獨的 Python 設定,同時共享系統範圍的基礎安裝,以便於維護。虛擬環境有自己的一組私有站點包(即本地安裝的庫),並且可以選擇與系統範圍的站點包隔離。它們的概念和實現受流行的 virtualenv
第三方包的啟發,但受益於與直譯器核心的更緊密整合。
此 PEP 添加了 venv
模組以進行程式設計訪問,以及 pyvenv
指令碼以進行命令列訪問和管理。Python 直譯器檢查 pyvenv.cfg
檔案,該檔案的存在表示虛擬環境目錄樹的根。
另請參閱
- PEP 405 - Python 虛擬環境
PEP 由 Carl Meyer 編寫;由 Carl Meyer 和 Vinay Sajip 實現
PEP 420: 隱式名稱空間包¶
對不需要 __init__.py
標記檔案的包目錄的本機支援,並且可以自動跨多個路徑段(受名稱空間包的各種第三方方法的啟發,如 PEP 420 中所述)
另請參閱
- PEP 420 - 隱式名稱空間包
PEP 由 Eric V. Smith 編寫;由 Eric V. Smith 和 Barry Warsaw 實現
PEP 3118: 新的 memoryview 實現和緩衝區協議文件¶
PEP 3118 的實現已得到顯著改進。
新的 memoryview 實現全面修復了 Py_buffer 結構中動態分配欄位的所有權和生命週期問題,這些問題導致了多次崩潰報告。此外,還修復了一些對於非連續或多維輸入崩潰或返回不正確結果的函式。
memoryview 物件現在具有符合 PEP-3118 的 getbufferproc(),該函式檢查使用者的請求型別。添加了許多新特性,其中大多數都完全適用於非連續陣列和具有子偏移的陣列。
文件已更新,明確說明了匯出者和使用者的責任。緩衝區請求標誌分為基本標誌和複合標誌。解釋了非連續和多維 NumPy 風格陣列的記憶體佈局。
特性¶
現在支援 struct 模組語法中的所有本機單字元格式說明符(可以選擇以“@”為字首)。
在某些限制下,cast() 方法允許更改 C 連續陣列的格式和形狀。
支援任何陣列型別的多維列表表示。
支援任何陣列型別的多維比較。
現在,具有格式 B、b 或 c 的可雜湊(只讀)型別的一維 memoryview 是可雜湊的。(由 Antoine Pitrou 在 bpo-13411 中貢獻。)
支援任何 1-D 陣列型別的任意切片。例如,現在可以使用負步長以 O(1) 的時間複雜度反轉 memoryview。
API 更改¶
維度的最大數量正式限制為 64。
空形狀、步幅和子偏移的表示現在是一個空元組,而不是
None
。現在,訪問格式為“B”(無符號位元組)的 memoryview 元素會返回一個整數(符合 struct 模組語法)。要返回位元組物件,必須首先將檢視轉換為“c”。
memoryview 比較現在使用運算元的邏輯結構,並按值比較所有陣列元素。支援 struct 模組語法中的所有格式字串。仍然允許使用無法識別的格式字串的檢視,但無論檢視內容如何,它們始終被比較為不相等。
有關更多更改,請參閱構建和 C API 更改和移植 C 程式碼。
(由 Stefan Krah 在 bpo-10181 中貢獻。)
另請參閱
PEP 3118 - 修訂緩衝區協議
PEP 393: 靈活的字串表示¶
Unicode 字串型別已更改為支援多種內部表示形式,具體取決於所表示字串中具有最大 Unicode 序號的字元(1、2 或 4 位元組)。這允許在常見情況下進行空間高效的表示,但可以在所有系統上訪問完整的 UCS-4。為了與現有 API 相容,可能會並行存在多種表示形式;隨著時間的推移,這種相容性應該逐步淘汰。
在 Python 方面,此更改應該沒有任何缺點。
在 C API 方面,PEP 393 是完全向後相容的。舊版 API 至少應保留五年。使用舊版 API 的應用程式不會完全受益於記憶體的減少,或者更糟糕的是,可能會使用更多的記憶體,因為 Python 可能需要維護每個字串的兩個版本(舊版格式和新的高效儲存)。
功能¶
由 PEP 393 引入的更改如下
Python 現在始終支援完整的 Unicode 程式碼點範圍,包括非 BMP 程式碼點(即從
U+0000
到U+10FFFF
)。窄版本和寬版本之間的區別不再存在,Python 現在的行為類似於寬版本,即使在 Windows 下也是如此。隨著窄版本的消亡,特定於窄版本的問題也已得到修復,例如
len()
現在對於非 BMP 字元始終返回 1,因此len('\U0010FFFF') == 1
;代理對不會在字串字面量中重新組合,因此
'\uDBFF\uDFFF' != '\U0010FFFF'
;索引或切片非 BMP 字元會返回期望的值,因此
'\U0010FFFF'[0]
現在返回'\U0010FFFF'
,而不是'\uDBFF'
;標準庫中的所有其他函式現在都可以正確處理非 BMP 程式碼點。
sys.maxunicode
的值現在始終為1114111
(十六進位制為0x10FFFF
)。為了向後相容,PyUnicode_GetMax()
函式仍然返回0xFFFF
或0x10FFFF
,並且不應將其與新的 Unicode API 一起使用(請參閱 bpo-13054)。./configure
標誌--with-wide-unicode
已被刪除。
效能和資源使用¶
Unicode 字串的儲存現在取決於字串中的最高程式碼點
純 ASCII 和 Latin1 字串(
U+0000-U+00FF
)每個程式碼點使用 1 個位元組;BMP 字串(
U+0000-U+FFFF
)每個程式碼點使用 2 個位元組;非 BMP 字串(
U+10000-U+10FFFF
)每個程式碼點使用 4 個位元組。
最終的結果是,對於大多數應用程式,字串儲存的記憶體使用量應該會顯著減少——特別是與以前的寬 Unicode 版本相比——因為在許多情況下,即使在國際環境中,字串也將是純 ASCII 字串(因為許多字串儲存非人類語言資料,例如 XML 片段、HTTP 標頭、JSON 編碼的資料等)。我們還希望,出於相同的原因,它將提高非平凡應用程式的 CPU 快取效率。在 Django 基準測試中,Python 3.3 的記憶體使用量比 Python 3.2 小兩到三倍,並且比 Python 2.7 好一點(有關詳細資訊,請參閱 PEP)。
另請參閱
- PEP 393 - 靈活的字串表示
由 Martin von Löwis 編寫的 PEP;由 Torsten Becker 和 Martin von Löwis 實現。
PEP 397:Windows 的 Python 啟動器¶
Python 3.3 Windows 安裝程式現在包含一個 py
啟動器應用程式,該應用程式可以用來以與版本無關的方式啟動 Python 應用程式。
雙擊 *.py
檔案時會隱式呼叫此啟動器。如果系統上只安裝了一個 Python 版本,則該版本將用於執行該檔案。如果安裝了多個版本,則預設情況下使用最新版本,但這可以透過在 Python 指令碼中包含 Unix 風格的“shebang 行”來覆蓋。
也可以從命令列顯式使用啟動器作為 py
應用程式。執行 py
遵循與隱式啟動指令碼相同的版本選擇規則,但是可以透過傳遞適當的引數來選擇更具體的版本(例如,當也安裝了 Python 2 時,使用 -3
來請求 Python 3,或者當安裝了更新的版本時,使用 -2.6
來明確請求更早版本的 Python)。
除了啟動器外,Windows 安裝程式現在還包括一個選項,可將新安裝的 Python 新增到系統 PATH 中。(由 Brian Curtin 在 bpo-3561 中貢獻。)
另請參閱
- PEP 397 - Windows 的 Python 啟動器
由 Mark Hammond 和 Martin v. Löwis 編寫的 PEP;由 Vinay Sajip 實現。
啟動器文件: Windows 的 Python 啟動器
安裝程式 PATH 修改: 查詢 Python 可執行檔案
PEP 3151:重新設計 OS 和 IO 異常層次結構¶
現在,由作業系統錯誤引發的異常層次結構既簡化又更加精細。
您不必再擔心在 OSError
、IOError
、EnvironmentError
、WindowsError
、mmap.error
、socket.error
或 select.error
之間選擇適當的異常型別。所有這些異常型別現在只有一個:OSError
。其他名稱保留為別名,以實現相容性。
此外,現在更容易捕獲特定的錯誤情況。您可以捕獲適當的 OSError
子類,而不是檢查 errno
屬性(或 args[0]
)以查詢 errno
模組中的特定常量。可用的子類如下
並且 ConnectionError
本身具有更精細的子類
由於有了新的異常,現在可以避免 errno
的常見用法。例如,為 Python 3.2 編寫的以下程式碼
from errno import ENOENT, EACCES, EPERM
try:
with open("document.txt") as f:
content = f.read()
except IOError as err:
if err.errno == ENOENT:
print("document.txt file is missing")
elif err.errno in (EACCES, EPERM):
print("You are not allowed to read document.txt")
else:
raise
現在可以編寫,而無需 errno
匯入和手動檢查異常屬性
try:
with open("document.txt") as f:
content = f.read()
except FileNotFoundError:
print("document.txt file is missing")
except PermissionError:
print("You are not allowed to read document.txt")
另請參閱
- PEP 3151 - 重新設計 OS 和 IO 異常層次結構
由 Antoine Pitrou 編寫和實現的 PEP
PEP 380:委託給子生成器的語法¶
PEP 380 添加了 yield from
表示式,允許 生成器 將其部分操作委託給另一個生成器。這允許將包含 yield
的程式碼段分解出來並放置在另一個生成器中。此外,允許子生成器返回一個值,並且該值可用於委託生成器。
儘管主要設計用於委託給子生成器,但 yield from
表示式實際上允許委託給任意子迭代器。
對於簡單的迭代器,yield from iterable
本質上只是 for item in iterable: yield item
的縮寫形式。
>>> def g(x):
... yield from range(x, 0, -1)
... yield from range(x)
...
>>> list(g(5))
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4]
然而,與普通迴圈不同,yield from
允許子生成器直接從呼叫作用域接收發送值和丟擲值,並將最終值返回給外部生成器。
>>> def accumulate():
... tally = 0
... while 1:
... next = yield
... if next is None:
... return tally
... tally += next
...
>>> def gather_tallies(tallies):
... while 1:
... tally = yield from accumulate()
... tallies.append(tally)
...
>>> tallies = []
>>> acc = gather_tallies(tallies)
>>> next(acc) # Ensure the accumulator is ready to accept values
>>> for i in range(4):
... acc.send(i)
...
>>> acc.send(None) # Finish the first tally
>>> for i in range(5):
... acc.send(i)
...
>>> acc.send(None) # Finish the second tally
>>> tallies
[6, 10]
推動此更改的主要原則是,即使是那些設計為與 send
和 throw
方法一起使用的生成器,也可以像將一個大型函式拆分成多個子函式一樣輕鬆地拆分成多個子生成器。
另請參閱
- PEP 380 - 委託給子生成器的語法
PEP 由 Greg Ewing 撰寫;由 Greg Ewing 實現,由 Renaud Blanch、Ryan Kelly 和 Nick Coghlan 整合到 3.3 版本中;由 Zbigniew Jędrzejewski-Szmek 和 Nick Coghlan 編寫文件。
PEP 409:抑制異常上下文¶
PEP 409 引入了新的語法,允許停用鏈式異常上下文的顯示。這使得在異常型別之間轉換的應用程式中可以顯示更清晰的錯誤訊息。
>>> class D:
... def __init__(self, extra):
... self._extra_attributes = extra
... def __getattr__(self, attr):
... try:
... return self._extra_attributes[attr]
... except KeyError:
... raise AttributeError(attr) from None
...
>>> D({}).x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: x
如果沒有 from None
字尾來抑制原因,預設情況下將顯示原始異常。
>>> class C:
... def __init__(self, extra):
... self._extra_attributes = extra
... def __getattr__(self, attr):
... try:
... return self._extra_attributes[attr]
... except KeyError:
... raise AttributeError(attr)
...
>>> C({}).x
Traceback (most recent call last):
File "<stdin>", line 6, in __getattr__
KeyError: 'x'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: x
不會丟失任何除錯功能,因為如果需要,原始異常上下文仍然可用(例如,如果中間庫錯誤地抑制了有價值的底層細節)。
>>> try:
... D({}).x
... except AttributeError as exc:
... print(repr(exc.__context__))
...
KeyError('x',)
另請參閱
- PEP 409 - 抑制異常上下文
PEP 由 Ethan Furman 撰寫;由 Ethan Furman 和 Nick Coghlan 實現。
PEP 414:顯式 Unicode 字面量¶
為了簡化從 Python 2 到大量使用 Unicode 字面量的 Unicode 感知 Python 應用程式的過渡,Python 3.3 再次支援字串字面量的 “u
” 字首。此字首在 Python 3 中沒有語義意義,它僅用於減少遷移到 Python 3 中的純機械更改的數量,使開發人員更容易專注於更重要的語義更改(例如,更嚴格地預設分離二進位制資料和文字資料)。
另請參閱
- PEP 414 - 顯式 Unicode 字面量
PEP 由 Armin Ronacher 撰寫。
PEP 3155:類和函式的限定名稱¶
函式和類物件有一個新的 __qualname__
屬性,表示從模組頂層到其定義的“路徑”。對於全域性函式和類,這與 __name__
相同。對於其他函式和類,它提供了關於它們實際定義位置以及如何從全域性作用域訪問它們的更好資訊。
非繫結方法的示例
>>> class C:
... def meth(self):
... pass
...
>>> C.meth.__name__
'meth'
>>> C.meth.__qualname__
'C.meth'
巢狀類的示例
>>> class C:
... class D:
... def meth(self):
... pass
...
>>> C.D.__name__
'D'
>>> C.D.__qualname__
'C.D'
>>> C.D.meth.__name__
'meth'
>>> C.D.meth.__qualname__
'C.D.meth'
巢狀函式的示例
>>> def outer():
... def inner():
... pass
... return inner
...
>>> outer().__name__
'inner'
>>> outer().__qualname__
'outer.<locals>.inner'
這些物件的字串表示形式也已更改,以包含新的、更精確的資訊。
>>> str(C.D)
"<class '__main__.C.D'>"
>>> str(C.D.meth)
'<function C.D.meth at 0x7f46b9fe31e0>'
另請參閱
- PEP 3155 - 類和函式的限定名稱
PEP 由 Antoine Pitrou 撰寫和實現。
PEP 412:金鑰共享字典¶
用於儲存物件屬性的字典現在能夠在彼此之間共享部分內部儲存(即,儲存鍵及其各自雜湊值的部分)。這減少了建立大量非內建型別例項的程式的記憶體消耗。
另請參閱
- PEP 412 - 金鑰共享字典
PEP 由 Mark Shannon 撰寫和實現。
PEP 362:函式簽名物件¶
一個新的函式 inspect.signature()
使對 python 可呼叫物件的內省變得容易且直接。支援廣泛的可呼叫物件:python 函式(帶或不帶裝飾器)、類和 functools.partial()
物件。新的類 inspect.Signature
、inspect.Parameter
和 inspect.BoundArguments
儲存有關呼叫簽名的資訊,例如,註解、預設值、引數型別和繫結引數,這大大簡化了編寫裝飾器以及任何驗證或修改呼叫簽名或引數的程式碼。
另請參閱
- PEP 362: - 函式簽名物件
PEP 由 Brett Cannon、Yury Selivanov、Larry Hastings、Jiwon Seo 撰寫;由 Yury Selivanov 實現。
PEP 421:新增 sys.implementation¶
sys
模組上的一個新屬性公開了當前正在執行的直譯器實現的特定細節。sys.implementation
上的初始屬性集為 name
、version
、hexversion
和 cache_tag
。
sys.implementation
的目的是將標準庫使用的特定於實現的資料整合到一個名稱空間中。這使得不同的 Python 實現可以更容易地共享單個標準庫程式碼庫。在其初始狀態下,sys.implementation
僅保留一小部分特定於實現的資料。隨著時間的推移,該比例將發生變化,以使標準庫更具可移植性。
改進標準庫可移植性的一個例子是 cache_tag
。從 Python 3.3 開始,sys.implementation.cache_tag
被 importlib
用來支援 PEP 3147 的合規性。任何使用 importlib
作為其內建匯入系統的 Python 實現都可以使用 cache_tag
來控制模組的快取行為。
SimpleNamespace¶
sys.implementation
的實現還為 Python 引入了一個新型別:types.SimpleNamespace
。與基於對映的名稱空間(如 dict
)相比,SimpleNamespace
是基於屬性的,如 object
。但是,與 object
不同,SimpleNamespace
例項是可寫的。這意味著您可以透過普通的屬性訪問來新增、刪除和修改名稱空間。
另請參閱
- PEP 421 - 新增 sys.implementation
PEP 由 Eric Snow 撰寫和實現。
使用 importlib 作為匯入的實現¶
bpo-2377 - 將 __import__ 替換為 importlib.__import__ bpo-13959 - 在純 Python 中重新實現 imp
的部分 bpo-14605 - 使匯入機制明確 bpo-14646 - 要求載入器設定 __loader__ 和 __package__
現在,__import__()
函式由 importlib.__import__()
提供支援。這項工作完成了 PEP 302 的“第二階段”。此更改帶來了多重好處。首先,它允許更多用於支援匯入的機制被公開,而不是隱式地隱藏在 C 程式碼中。它還為所有支援 Python 3.3 的 Python 虛擬機器提供了一個統一的實現,有助於結束匯入語義中任何虛擬機器特定的偏差。最後,它簡化了匯入的維護,允許未來進行擴充套件。
對於普通使用者來說,語義上應該沒有明顯的改變。對於那些目前操作匯入或以程式設計方式呼叫匯入的程式碼,可能需要的程式碼更改將在本文件的 移植 Python 程式碼 部分中介紹。
新的 API¶
這項工作的一大好處是公開了使匯入語句工作的原理。這意味著曾經隱式的各種匯入器現在都完全作為 importlib
包的一部分公開出來。
定義在 importlib.abc
中的抽象基類已經擴充套件,透過引入 importlib.abc.MetaPathFinder
和 importlib.abc.PathEntryFinder
,來正確區分 元路徑查詢器 和 路徑條目查詢器。舊的 importlib.abc.Finder
抽象基類現在僅為了向後相容性而提供,並且不強制任何方法要求。
就查詢器而言,importlib.machinery.FileFinder
公開了用於搜尋模組的原始檔和位元組碼檔案的機制。以前,此類是 sys.path_hooks
的隱式成員。
對於載入器,新的抽象基類 importlib.abc.FileLoader
有助於編寫一個使用檔案系統作為模組程式碼儲存機制的載入器。現在可以直接使用原始檔的載入器 (importlib.machinery.SourceFileLoader
)、無源位元組碼檔案的載入器 (importlib.machinery.SourcelessFileLoader
) 和擴充套件模組的載入器 (importlib.machinery.ExtensionFileLoader
)。
現在,ImportError
具有 name
和 path
屬性,當有相關資料提供時會設定這些屬性。現在,匯入失敗的訊息還將提供模組的完整名稱,而不僅僅是模組名稱的末尾部分。
現在,importlib.invalidate_caches()
函式將呼叫快取在 sys.path_importer_cache
中的所有查詢器上的同名方法,以幫助清理任何必要的儲存狀態。
可見的更改¶
有關程式碼的潛在所需更改,請參閱 移植 Python 程式碼 部分。
除了 importlib
現在公開的內容之外,匯入還有其他可見的更改。最大的變化是 sys.meta_path
和 sys.path_hooks
現在儲存匯入使用的所有元路徑查詢器和路徑條目鉤子。以前,查詢器是隱式的並隱藏在匯入的 C 程式碼中,而不是直接暴露出來。這意味著現在可以輕鬆地刪除或更改各種查詢器的順序以滿足需求。
另一個變化是,所有模組都有一個 __loader__
屬性,用於儲存建立模組的載入器。 PEP 302 已經更新,使這個屬性對於載入器來說是強制實現的,因此在未來,一旦第三方載入器更新後,人們就可以依賴該屬性的存在。但在那時之前,匯入是在載入後設置模組的。
載入器現在還需要根據 PEP 366 設定 __package__
屬性。同樣,匯入本身已經為 importlib
中的所有載入器設定了此屬性,並且匯入本身是在載入後設置該屬性的。
當在 sys.path_hooks
上找不到查詢器時,現在會將 None
插入到 sys.path_importer_cache
中。由於 imp.NullImporter
沒有直接在 sys.path_hooks
上公開,因此不能再依賴它始終可用作表示未找到查詢器的值。
所有其他更改都與語義更改有關,在為 Python 3.3 更新程式碼時應考慮這些更改,因此應在本文件的 移植 Python 程式碼 部分中閱讀相關資訊。
(由 Brett Cannon 實現)
其他語言更改¶
對核心 Python 語言進行的一些較小的更改是
增加了對 Unicode 名稱別名和命名序列的支援。現在,
unicodedata.lookup()
和'\N{...}'
都解析名稱別名,並且unicodedata.lookup()
也解析命名序列。(由 Ezio Melotti 在 bpo-12753 中貢獻。)
Unicode 資料庫更新到 UCD 版本 6.1.0
現在,對
range()
物件進行相等比較會返回一個結果,反映由這些 range 物件生成的底層序列的相等性。(bpo-13201)現在,
bytes
和bytearray
物件的count()
、find()
、rfind()
、index()
和rindex()
方法接受一個介於 0 和 255 之間的整數作為它們的第一個引數。(由 Petri Lehtinen 在 bpo-12170 中貢獻。)
現在,
bytes
和bytearray
物件的rjust()
、ljust()
和center()
方法接受一個bytearray
作為fill
引數。(由 Petri Lehtinen 在 bpo-12380 中貢獻。)新的方法已新增到
list
和bytearray
:copy()
和clear()
(bpo-10516)。因此,MutableSequence
現在也定義了一個clear()
方法 (bpo-11388)。原始位元組字面值現在可以寫作
rb"..."
以及br"..."
。(由 Antoine Pitrou 在 bpo-13748 中貢獻。)
dict.setdefault()
現在只對給定的鍵執行一次查詢,使其在與內建型別一起使用時具有原子性。(由 Filip Gruszczyński 在 bpo-13521 中貢獻。)
當函式呼叫與函式簽名不匹配時產生的錯誤訊息已得到顯著改進。
(由 Benjamin Peterson 貢獻。)
更細粒度的匯入鎖¶
之前的 CPython 版本始終依賴於全域性匯入鎖。這導致了意想不到的麻煩,例如當匯入模組會導致在另一個執行緒中執行程式碼作為副作用時,會出現死鎖。有時會採用笨拙的解決方法,例如 PyImport_ImportModuleNoBlock()
C API 函式。
在 Python 3.3 中,匯入模組會採用每個模組的鎖。這可以正確地序列化從多個執行緒匯入給定模組的操作(防止暴露不完全初始化的模組),同時消除上述麻煩。
(由 Antoine Pitrou 在 bpo-9260 中貢獻。)
內建函式和型別¶
open()
獲取一個新的 *opener* 引數:檔案物件的底層檔案描述符隨後透過使用 ( *file* , *flags* ) 呼叫 *opener* 來獲得。它可以用於使用自定義標誌,例如os.O_CLOEXEC
。添加了'x'
模式:以獨佔建立方式開啟,如果檔案已存在則失敗。print()
:添加了 *flush* 關鍵字引數。如果 *flush* 關鍵字引數為 true,則強制重新整理流。hash()
:預設啟用雜湊隨機化,請參閱object.__hash__()
和PYTHONHASHSEED
。str
型別獲取一個新的casefold()
方法:返回字串的 casefolded 副本,casefolded 字串可用於不區分大小寫的匹配。例如,'ß'.casefold()
返回'ss'
。序列文件已進行了大量重寫,以更好地解釋二進位制/文字序列的區別,併為各個內建序列型別提供特定的文件部分 (bpo-4966)。
新模組¶
faulthandler¶
這個新的除錯模組 faulthandler
包含一些函式,用於在發生故障(例如段錯誤)、超時後或在使用者訊號上顯式轉儲 Python 回溯資訊。呼叫 faulthandler.enable()
以安裝 SIGSEGV
、SIGFPE
、SIGABRT
、SIGBUS
和 SIGILL
訊號的故障處理程式。您還可以透過設定 PYTHONFAULTHANDLER
環境變數或使用 -X
faulthandler
命令列選項在啟動時啟用它們。
在 Linux 上發生段錯誤的示例
$ python -q -X faulthandler
>>> import ctypes
>>> ctypes.string_at(0)
Fatal Python error: Segmentation fault
Current thread 0x00007fb899f39700:
File "/home/python/cpython/Lib/ctypes/__init__.py", line 486 in string_at
File "<stdin>", line 1 in <module>
Segmentation fault
ipaddress¶
新的 ipaddress
模組提供了建立和操作表示 IPv4 和 IPv6 地址、網路和介面(即與特定 IP 子閘道器聯的 IP 地址)的物件的工具。
(由 Google 和 Peter Moody 在 PEP 3144 中貢獻。)
lzma¶
新新增的 lzma
模組使用 LZMA 演算法提供資料壓縮和解壓縮,包括對 .xz
和 .lzma
檔案格式的支援。
(由 Nadeem Vawda 和 Per Øyvind Karlsen 在 bpo-6715 中貢獻。)
改進的模組¶
abc¶
改進了對包含與抽象方法組合的描述符的抽象基類的支援。現在宣告抽象描述符的推薦方法是將 __isabstractmethod__
作為動態更新的屬性提供。內建描述符已相應更新。
abc.abstractproperty
已棄用,請改用帶有abc.abstractmethod()
的property
。abc.abstractclassmethod
已棄用,請改用帶有abc.abstractmethod()
的classmethod
。abc.abstractstaticmethod
已棄用,請改用帶有abc.abstractmethod()
的staticmethod
。
(由 Darren Dale 在 bpo-11610 中貢獻。)
abc.ABCMeta.register()
現在返回已註冊的子類,這意味著它現在可以用作類裝飾器 (bpo-10868)。
array¶
array
模組使用 q
和 Q
型別程式碼支援 long long 型別。
(由 Oren Tirosh 和 Hirokazu Yamamoto 在 bpo-1172711 中貢獻。)
base64¶
現在,base64
現代介面的解碼函式接受僅 ASCII 的 Unicode 字串。例如,base64.b64decode('YWJj')
返回 b'abc'
。(由 Catalin Iacob 在 bpo-13641 中貢獻。)
binascii¶
除了通常接受的二進位制物件外,a2b_
函式現在也都接受僅包含 ASCII 字元的字串作為輸入。(由 Antoine Pitrou 在 bpo-13637 中貢獻。)
bz2¶
bz2
模組已從頭開始重寫。在此過程中,添加了一些新功能
新的
bz2.open()
函式:以二進位制或文字模式開啟 bzip2 壓縮檔案。bz2.BZ2File
現在可以透過其建構函式的 fileobj 引數從任意類似檔案的物件讀取和寫入。(由 Nadeem Vawda 在 bpo-5863 中貢獻。)
bz2.BZ2File
和bz2.decompress()
現在可以解壓縮多流輸入(例如,由 pbzip2 工具生成的輸入)。bz2.BZ2File
現在也可以使用'a'
(追加)模式來建立這種型別的檔案。(由 Nir Aides 在 bpo-1625 中貢獻。)
bz2.BZ2File
現在實現了所有io.BufferedIOBase
API,除了detach()
和truncate()
方法。
codecs¶
mbcs
編解碼器已被重寫,以便在所有 Windows 版本上正確處理 replace
和 ignore
錯誤處理程式。mbcs
編解碼器現在支援所有錯誤處理程式,而不僅僅是 replace
進行編碼和 ignore
進行解碼。
添加了一個新的僅限 Windows 的編解碼器:cp65001
(bpo-13216)。它是 Windows 內碼表 65001(Windows UTF-8,CP_UTF8
)。例如,如果控制檯輸出內碼表設定為 cp65001(例如,使用 chcp 65001
命令),則 sys.stdout
會使用它。
多位元組 CJK 解碼器現在可以更快地重新同步。它們只會忽略無效位元組序列的第一個位元組。例如,b'\xff\n'.decode('gb2312', 'replace')
現在會在替換字元後返回一個 \n
。
增量 CJK 編解碼器編碼器不再在每次呼叫其 encode() 方法時重置。例如
>>> import codecs
>>> encoder = codecs.getincrementalencoder('hz')('strict')
>>> b''.join(encoder.encode(x) for x in '\u52ff\u65bd\u65bc\u4eba\u3002 Bye.')
b'~{NpJ)l6HK!#~} Bye.'
此示例在舊版本的 Python 中給出 b'~{Np~}~{J)~}~{l6~}~{HK~}~{!#~} Bye.'
。
unicode_internal
編解碼器已被棄用。
collections¶
添加了一個新的 ChainMap
類,以允許將多個對映視為一個單元。(由 Raymond Hettinger 為 bpo-11089 編寫,並在 bpo-11297 中公開發布。)
抽象基類已移動到新的 collections.abc
模組中,以更好地區分抽象集合類和具體集合類。collections
模組中仍然存在 ABC 的別名,以保留現有的匯入。(bpo-11085)
Counter
類現在支援一元 +
和 -
運算子,以及就地運算子 +=
、-=
、|=
和 &=
。(由 Raymond Hettinger 在 bpo-13121 中貢獻。)
contextlib¶
ExitStack
現在為以程式設計方式操作上下文管理器和類似的清理功能提供了堅實的基礎。與之前的 contextlib.nested
API(已棄用並刪除)不同,新的 API 旨在正確工作,無論上下文管理器是在其 __init__
方法(例如,檔案物件)還是在其 __enter__
方法(例如,來自 threading
模組的同步物件)中獲取其資源。
crypt¶
向 crypt
模組新增 salt 和模組化 crypt 格式(雜湊方法)以及 mksalt()
函式。
curses¶
如果
curses
模組連結到 ncursesw 庫,則在傳遞 Unicode 字串或字元時使用 Unicode 函式(例如waddwstr()
),否則使用位元組函式(例如waddstr()
)。使用區域設定編碼而不是
utf-8
來編碼 Unicode 字串。curses.window
有一個新的curses.window.encoding
屬性。curses.window
類有一個新的get_wch()
方法來獲取寬字元curses
模組有一個新的unget_wch()
函式,用於推送一個寬字元,以便下一個get_wch()
將返回它
(由 Iñigo Serna 在 bpo-6755 中貢獻。)
datetime¶
天真型和感知型
datetime
例項之間的相等比較現在返回False
,而不是引發TypeError
(bpo-15006)。新的
datetime.datetime.timestamp()
方法:返回與datetime
例項對應的 POSIX 時間戳。datetime.datetime.strftime()
方法支援格式化早於 1000 年的年份。datetime.datetime.astimezone()
方法現在可以在不帶引數的情況下呼叫,以將 datetime 例項轉換為系統時區。
decimal¶
- bpo-7652 - 整合快速本機十進位制算術。
由 Stefan Krah 編寫的 C 模組和 libmpdec。
十進位制模組的新 C 版本集成了高速 libmpdec 庫,用於任意精度正確舍入的十進位制浮點算術。libmpdec 符合 IBM 的通用十進位制算術規範。
效能提升幅度從資料庫應用的 10 倍到數值密集型應用的 100 倍不等。這些數字是十進位制浮點運算中使用的標準精度所期望的收益。由於精度是使用者可配置的,因此確切的數字可能會有所不同。例如,在整數大數算術中,差異可能明顯更大。
下表旨在作為說明。基準測試可在 https://www.bytereef.org/mpdecimal/quickstart.html 獲取。
decimal.py
_decimal
加速
pi
42.02秒
0.345秒
120倍
telco
172.19秒
5.68秒
30倍
psycopg
3.57秒
0.29秒
12倍
特性¶
FloatOperation
訊號可以選擇性地為混合浮點數和十進位制數啟用更嚴格的語義。如果 Python 在編譯時沒有啟用執行緒,則 C 版本會自動停用昂貴的執行緒區域性上下文機制。在這種情況下,變數
HAVE_THREADS
將被設定為False
。
API 更改¶
C 模組具有以下上下文限制,具體取決於機器架構
32 位
64 位
MAX_PREC
425000000
999999999999999999
MAX_EMAX
425000000
999999999999999999
MIN_EMIN
-425000000
-999999999999999999
在上下文模板(
DefaultContext
、BasicContext
和ExtendedContext
)中,Emax
和Emin
的幅度已更改為999999
。decimal.py 中的
Decimal
建構函式不遵守上下文限制,並精確轉換具有任意指數或精度的值。由於 C 版本具有內部限制,因此使用以下方案:如果可能,則精確轉換值,否則引發InvalidOperation
異常,結果為 NaN。在後一種情況下,始終可以使用create_decimal()
以獲得舍入或不精確的值。decimal.py 中的冪函式始終正確舍入。在 C 版本中,它根據正確舍入的
exp()
和ln()
函式定義,但最終結果僅“幾乎始終正確舍入”。在 C 版本中,包含訊號的上下文字典是
MutableMapping
。出於速度原因,flags
和traps
始終引用初始化上下文時使用的同一個MutableMapping
。如果分配了新的訊號字典,flags
和traps
將使用新值更新,但它們不引用 RHS 字典。為了使 Python 和 C 版本具有通用的交換格式,對
Context
進行 pickle 操作會產生不同的輸出。quantize()
方法中的watchexp
引數已棄用。
電子郵件¶
策略框架¶
電子郵件包現在有一個 policy
框架。Policy
是一個具有多個方法和屬性的物件,用於控制電子郵件包的行為。Python 3.3 的主要策略是 Compat32
策略,該策略提供與 Python 3.2 中電子郵件包的向後相容性。當電子郵件訊息被 parser
解析時,或者當建立 Message
物件時,或者當使用 generator
序列化電子郵件時,可以指定 policy
。除非被覆蓋,否則傳遞給 parser
的策略會被 parser
建立的所有 Message
物件和子物件繼承。預設情況下,generator
將使用它正在序列化的 Message
物件的策略。預設策略是 compat32
。
所有 policy
物件實現的最少控制集是
max_line_length |
當序列化 |
linesep |
當序列化 |
cte_type |
|
raise_on_defect |
導致 |
使用策略物件的 clone()
方法建立具有新設定的新策略例項。clone
將上述任何控制元件作為關鍵字引數。呼叫中未指定的任何控制元件都保留其預設值。因此,您可以建立一個像這樣使用 \r\n
行分隔符字元的策略
mypolicy = compat32.clone(linesep='\r\n')
可以使用策略來簡化應用程式所需的格式的訊息生成。無需記住在所有呼叫 generator
的地方指定 linesep='\r\n'
,您可以在設定 parser
或 Message
使用的策略時指定一次,無論您的程式使用哪個來建立 Message
物件。另一方面,如果您需要生成多種形式的訊息,您仍然可以在相應的 generator
呼叫中指定引數。或者,您可以為不同的情況使用自定義策略例項,並在建立 generator
時傳入這些例項。
帶有新標頭 API 的臨時策略¶
儘管策略框架本身就很有價值,但引入它的主要動機是允許建立新的策略,以一種為不使用新策略的使用者保持向後相容性的方式,為電子郵件包實現新功能。由於新策略引入了新的 API,我們在 Python 3.3 中將其作為臨時策略釋出。如果核心開發人員認為有必要,可能會發生向後不相容的更改(包括刪除程式碼)。
新的策略是 EmailPolicy
的例項,並添加了以下附加控制:
refold_source |
控制由 |
header_factory |
一個可呼叫物件,它接受一個 |
header_factory
是新策略提供的關鍵新功能。當使用新的策略之一時,從 Message
物件檢索的任何標頭都是由 header_factory
生成的物件,並且任何時候你在 Message
上設定標頭時,它都會成為由 header_factory
生成的物件。所有此類標頭物件都有一個等於標頭名稱的 name
屬性。地址和日期標頭具有額外的屬性,使你可以訪問標頭的解析資料。這意味著你現在可以這樣做:
>>> m = Message(policy=SMTP)
>>> m['To'] = 'Éric <foo@example.com>'
>>> m['to']
'Éric <foo@example.com>'
>>> m['to'].addresses
(Address(display_name='Éric', username='foo', domain='example.com'),)
>>> m['to'].addresses[0].username
'foo'
>>> m['to'].addresses[0].display_name
'Éric'
>>> m['Date'] = email.utils.localtime()
>>> m['Date'].datetime
datetime.datetime(2012, 5, 25, 21, 39, 24, 465484, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000), 'EDT'))
>>> m['Date']
'Fri, 25 May 2012 21:44:27 -0400'
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <foo@example.com>
Date: Fri, 25 May 2012 21:44:27 -0400
你會注意到,當訊息被序列化時,Unicode 顯示名稱會自動編碼為 utf-8
,但當直接訪問標頭時,你會獲得 Unicode 版本。這消除了處理 email.header
decode_header()
或 make_header()
函式的任何需要。
你也可以從各個部分建立地址
>>> m['cc'] = [Group('pals', [Address('Bob', 'bob', 'example.com'),
... Address('Sally', 'sally', 'example.com')]),
... Address('Bonzo', addr_spec='bonz@laugh.com')]
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <foo@example.com>
Date: Fri, 25 May 2012 21:44:27 -0400
cc: pals: Bob <bob@example.com>, Sally <sally@example.com>;, Bonzo <bonz@laugh.com>
解碼為 Unicode 是自動完成的
>>> m2 = message_from_string(str(m))
>>> m2['to']
'Éric <foo@example.com>'
當你解析訊息時,你可以使用標頭物件的 addresses
和 groups
屬性來訪問組和單個地址
>>> m2['cc'].addresses
(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com'), Address(display_name='Bonzo', username='bonz', domain='laugh.com'))
>>> m2['cc'].groups
(Group(display_name='pals', addresses=(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com')), Group(display_name=None, addresses=(Address(display_name='Bonzo', username='bonz', domain='laugh.com'),))
總而言之,如果你使用新的策略之一,標頭操作的工作方式應該如下:你的應用程式使用 Unicode 字串,而電子郵件包透明地將 Unicode 編碼和解碼為 RFC 標準內容傳輸編碼,反之亦然。
其他 API 更改¶
新的 BytesHeaderParser
,新增到 parser
模組以補充 HeaderParser
並完成 Bytes API。
新的實用函式
format_datetime()
:給定一個datetime
,生成一個格式化的字串,用於電子郵件標頭。parsedate_to_datetime()
:給定一個來自電子郵件標頭的日期字串,將其轉換為一個感知時區的datetime
,如果偏移量為-0000
,則轉換為一個樸素的datetime
。localtime()
:沒有引數時,返回當前本地時間,作為使用本地timezone
的感知時區的datetime
。給定一個感知時區的datetime
,將其轉換為使用本地timezone
的感知時區的datetime
。
ftplib¶
ftplib.FTP
現在接受一個source_address
關鍵字引數,以指定在建立傳出套接字時在繫結呼叫中用作源地址的(host, port)
。(由 Giampaolo Rodolà 在 bpo-8594 中貢獻。)FTP_TLS
類現在提供一個新的ccc()
函式,用於將控制通道恢復為純文字。這對於利用那些知道如何使用非安全 FTP 處理 NAT 而無需開啟固定埠的防火牆很有用。(由 Giampaolo Rodolà 在 bpo-12139 中貢獻。)添加了
ftplib.FTP.mlsd()
方法,該方法提供了可解析的目錄列表格式,並棄用了ftplib.FTP.nlst()
和ftplib.FTP.dir()
。(由 Giampaolo Rodolà 在 bpo-11072 中貢獻。)
functools¶
functools.lru_cache()
裝飾器現在接受一個 typed
關鍵字引數(預設為 False
),以確保它在單獨的快取槽中快取比較相等的不同型別的值。(由 Raymond Hettinger 在 bpo-13227 中貢獻。)
gc¶
現在可以使用新的 callbacks
列表來註冊在垃圾回收器進行回收之前和之後呼叫的回撥。
hmac¶
添加了一個新的 compare_digest()
函式,以防止透過時間分析對摘要進行側通道攻擊。(由 Nick Coghlan 和 Christian Heimes 在 bpo-15061 中貢獻。)
http¶
http.server.BaseHTTPRequestHandler
現在會緩衝頭部資訊,並在呼叫 end_headers()
時一次性寫入所有頭部資訊。新的方法 flush_headers()
可用於直接管理何時傳送累積的頭部資訊。(由 Andrew Schaaf 在 bpo-3709 中貢獻。)
http.server
現在生成有效的 HTML 4.01 strict
輸出。(由 Ezio Melotti 在 bpo-13295 中貢獻。)
http.client.HTTPResponse
現在具有 readinto()
方法,這意味著它可以被用作 io.RawIOBase
類。(由 John Kuhn 在 bpo-13464 中貢獻。)
html¶
html.parser.HTMLParser
現在能夠解析破損的標記,而不會引發錯誤,因此建構函式的 strict 引數和 HTMLParseError
異常現在已被棄用。 解析破損標記的能力是大量錯誤修復的結果,這些修復也適用於 Python 2.7/3.2 的最新錯誤修復版本。(由 Ezio Melotti 在 bpo-15114 和 bpo-14538, bpo-13993, bpo-13960, bpo-13358, bpo-1745761, bpo-755670, bpo-13357, bpo-12629, bpo-1200313, bpo-670664, bpo-13273, bpo-12888, bpo-7311 中貢獻。)
一個新的 html5
字典,它將 HTML5 命名的字元引用對映到等效的 Unicode 字元(例如,html5['gt;'] == '>'
),已被新增到 html.entities
模組。 該字典現在也被 HTMLParser
使用。(由 Ezio Melotti 在 bpo-11113 和 bpo-15156 中貢獻。)
imaplib¶
IMAP4_SSL
建構函式現在接受 SSLContext 引數以控制安全通道的引數。
(由 Sijin Joseph 在 bpo-8808 中貢獻。)
inspect¶
添加了一個新的 getclosurevars()
函式。 此函式報告從函式體引用的所有名稱的當前繫結,以及這些名稱的解析位置,從而更容易在測試依賴於有狀態閉包的程式碼時驗證正確的內部狀態。
(由 Meador Inge 和 Nick Coghlan 在 bpo-13062 中貢獻。)
添加了一個新的 getgeneratorlocals()
函式。 此函式報告生成器堆疊幀中區域性變數的當前繫結,從而更容易在測試生成器時驗證正確的內部狀態。
(由 Meador Inge 在 bpo-15153 中貢獻。)
io¶
open()
函式有一個新的 'x'
模式,可用於獨佔地建立新檔案,如果該檔案已存在,則會引發 FileExistsError
。 它基於 C11 的 fopen() ‘x’ 模式。
(由 David Townshend 在 bpo-12760 中貢獻。)
TextIOWrapper
類的建構函式有一個新的可選引數 write_through。 如果 write_through 為 True
,則保證對 write()
的呼叫不會被緩衝:寫入 TextIOWrapper
物件的任何資料都會立即處理到其底層二進位制緩衝區。
itertools¶
accumulate()
現在接受可選的 func
引數,用於提供使用者提供的二元函式。
logging¶
basicConfig()
函式現在支援一個可選的 handlers
引數,該引數接受要新增到根記錄器的處理程式的迭代。
已向 SysLogHandler
添加了一個類級別屬性 append_nul
,以允許控制將 NUL
( \000
) 位元組附加到系統日誌記錄,因為某些守護程序需要它,而另一些守護程序則將其傳遞到日誌。
math¶
math
模組有一個新函式 log2()
,它返回 x 的以 2 為底的對數。
(由 Mark Dickinson 在 bpo-11888 中編寫。)
mmap¶
read()
方法現在與其他類似檔案的物件更加相容:如果省略了引數或指定為 None
,它將返回從當前檔案位置到對映末尾的位元組。(由 Petri Lehtinen 在 bpo-12021 中貢獻。)
multiprocessing¶
新的 multiprocessing.connection.wait()
函式允許使用超時輪詢多個物件(例如連線、套接字和管道)。(由 Richard Oudkerk 在 bpo-12328 中貢獻。)
multiprocessing.Connection
物件現在可以在多處理連線上傳輸。(由 Richard Oudkerk 在 bpo-4892 中貢獻。)
multiprocessing.Process
現在接受一個 daemon
關鍵字引數,以覆蓋從父程序繼承 daemon
標誌的預設行為 (bpo-6064)。
新屬性 multiprocessing.Process.sentinel
允許程式使用適當的作業系統原語一次等待多個 Process
物件(例如,在 posix 系統上使用 select
)。
新的方法 multiprocessing.pool.Pool.starmap()
和 starmap_async()
提供了與現有 multiprocessing.pool.Pool.map()
和 map_async()
函式等效的 itertools.starmap()
功能。(由 Hynek Schlawack 在 bpo-12708 中貢獻。)
nntplib¶
nntplib.NNTP
類現在支援上下文管理協議,以便無條件地捕獲 socket.error
異常並在完成後關閉 NNTP 連線
>>> from nntplib import NNTP
>>> with NNTP('news.gmane.org') as n:
... n.group('gmane.comp.python.committers')
...
('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers')
>>>
(由 Giampaolo Rodolà 在 bpo-9795 中貢獻。)
os¶
os
模組有一個新的pipe2()
函式,它允許建立一個帶有原子設定O_CLOEXEC
或O_NONBLOCK
標誌的管道。這對於避免多執行緒程式中的競爭條件尤其有用。os
模組有一個新的sendfile()
函式,它提供了一種高效的“零複製”方式,用於將資料從一個檔案(或套接字)描述符複製到另一個檔案(或套接字)描述符。“零複製”是指兩個描述符之間的資料複製完全由核心完成,而無需將資料複製到使用者空間緩衝區。“零複製”是指兩個描述符之間的資料複製完全由核心完成,而無需將資料複製到使用者空間緩衝區。sendfile()
可用於高效地將資料從磁碟上的檔案複製到網路套接字,例如用於下載檔案。(由 Ross Lagerwall 和 Giampaolo Rodolà 在 bpo-10882 中提交。)
為了避免像符號連結攻擊以及臨時檔案和目錄問題這樣的競爭條件,操作檔案描述符而不是檔名更可靠(也更快)。Python 3.3 增強了現有函式並引入了新的函式來處理檔案描述符(bpo-4761, bpo-10755 和 bpo-14626)。
os
模組有一個新的fwalk()
函式,它類似於walk()
,但它也會產生引用訪問目錄的檔案描述符。這對於避免符號連結競爭尤其有用。以下函式獲取新的可選 dir_fd (相對於目錄描述符的路徑)和/或 follow_symlinks (不跟隨符號連結):
access()
,chflags()
,chmod()
,chown()
,link()
,lstat()
,mkdir()
,mkfifo()
,mknod()
,open()
,readlink()
,remove()
,rename()
,replace()
,rmdir()
,stat()
,symlink()
,unlink()
,utime()
。可以透過集合os.supports_dir_fd
和os.supports_follows_symlinks
檢查使用這些引數的平臺支援情況。以下函式現在支援其路徑引數的檔案描述符:
chdir()
,chmod()
,chown()
,execve()
,listdir()
,pathconf()
,exists()
,stat()
,statvfs()
,utime()
。可以透過os.supports_fd
集合檢查此平臺的平臺支援情況。
access()
接受一個effective_ids
關鍵字引數,以啟用在訪問檢查中使用有效的 uid/gid 而不是真實的 uid/gid。可以透過supports_effective_ids
集合檢查此平臺的平臺支援情況。os
模組有兩個新函式:getpriority()
和setpriority()
。它們可以用來獲取或設定程序的 nice 值/優先順序,方式類似於os.nice()
,但擴充套件到所有程序,而不僅僅是當前程序。(由 Giampaolo Rodolà 在 bpo-10784 中提交。)
新的
os.replace()
函式允許跨平臺重新命名檔案並覆蓋目標檔案。 使用os.rename()
,現有目標檔案在 POSIX 下會被覆蓋,但在 Windows 下會引發錯誤。(由 Antoine Pitrou 在 bpo-8828 中貢獻。)現在,stat 函式族(
stat()
,fstat()
和lstat()
)支援以納秒精度讀取檔案的時間戳。 對稱地,utime()
現在可以以納秒精度寫入檔案的時間戳。(由 Larry Hastings 在 bpo-14127 中貢獻。)新的
os.get_terminal_size()
函式查詢附加到檔案描述符的終端的大小。另請參閱shutil.get_terminal_size()
。(由 Zbigniew Jędrzejewski-Szmek 在 bpo-13609 中貢獻。)
支援 Linux 擴充套件屬性的新函式 (bpo-12720):
getxattr()
、listxattr()
、removexattr()
、setxattr()
。排程器的新介面。 這些函式控制作業系統如何為程序分配 CPU 時間。 新函式:
sched_get_priority_max()
、sched_get_priority_min()
、sched_getaffinity()
、sched_getparam()
、sched_getscheduler()
、sched_rr_get_interval()
、sched_setaffinity()
、sched_setparam()
、sched_setscheduler()
、sched_yield()
。控制檔案系統的新函式
posix_fadvise()
: 宣告以特定模式訪問資料的意圖,從而允許核心進行最佳化。posix_fallocate()
: 確保為檔案分配足夠的磁碟空間。sync()
: 強制將所有內容寫入磁碟。
其他新的 posix 函式
lockf()
: 在開啟的檔案描述符上應用、測試或移除 POSIX 鎖。pread()
: 從檔案描述符的偏移量處讀取,檔案偏移量保持不變。pwrite()
: 從偏移量處寫入檔案描述符,檔案偏移量保持不變。readv()
: 從檔案描述符讀取到多個可寫緩衝區中。truncate()
: 截斷與 *path* 對應的檔案,使其大小至多為 *length* 個位元組。waitid()
: 等待一個或多個子程序完成。writev()
: 將 *buffers* 的內容寫入檔案描述符,其中 *buffers* 是任意的緩衝區序列。getgrouplist()
(bpo-9344): 返回指定使用者所屬的組 ID 列表。
某些平臺現在支援
lseek()
函式的其他常量,例如os.SEEK_HOLE
和os.SEEK_DATA
。新常量
RTLD_LAZY
、RTLD_NOW
、RTLD_GLOBAL
、RTLD_LOCAL
、RTLD_NODELETE
、RTLD_NOLOAD
和RTLD_DEEPBIND
在支援它們的平臺上可用。 這些用於sys.setdlopenflags()
函式,並取代了ctypes
和DLFCN
中定義的類似常量。(由 Victor Stinner 在 bpo-13226 中貢獻。)為了簡化跨平臺支援,
os.symlink()
現在在非 Windows 平臺上接受(並忽略)target_is_directory
關鍵字引數。
pdb¶
現在不僅命令名稱可以使用 Tab 補全,它們的引數也可以使用。 例如,對於 break
命令,函式和檔名都可以補全。
(由 Georg Brandl 在 bpo-14210 中貢獻)
pickle¶
pickle.Pickler
物件現在有一個可選的 dispatch_table
屬性,允許設定每個 pickler 的規約函式。
(由 Richard Oudkerk 在 bpo-14166 中貢獻。)
pydoc¶
Tk GUI 和 serve()
函式已從 pydoc
模組中移除:pydoc -g
和 serve()
在 Python 3.2 中已被棄用。
re¶
str
正則表示式現在支援 \u
和 \U
轉義。
(由 Serhiy Storchaka 在 bpo-3665 中貢獻。)
sched¶
run()
現在接受一個 blocking 引數,當設定為 false 時,該方法將執行即將到期的已排程事件(如果有),然後立即返回。這在您希望在非阻塞應用程式中使用scheduler
的情況下非常有用。(由 Giampaolo Rodolà 在 bpo-13449 中貢獻。)scheduler
類現在可以在多執行緒環境中安全使用。(由 Josiah Carlson 和 Giampaolo Rodolà 在 bpo-8684 中貢獻。)scheduler
類建構函式的 timefunc 和 delayfunct 引數現在是可選的,預設值分別為time.time()
和time.sleep()
。(由 Chris Clark 在 bpo-13245 中貢獻。)enter()
和enterabs()
的 argument 引數現在是可選的。(由 Chris Clark 在 bpo-13245 中貢獻。)enter()
和enterabs()
現在接受一個 kwargs 引數。(由 Chris Clark 在 bpo-13245 中貢獻。)
select¶
Solaris 及其衍生平臺有一個新的類 select.devpoll
,用於透過 /dev/poll
實現高效能非同步套接字。(由 Jesús Cea Avión 在 bpo-6397 中貢獻。)
shlex¶
之前未記錄的輔助函式 quote
從 pipes
模組移動到了 shlex
模組並被記錄。quote()
正確轉義了字串中所有可能被 shell 賦予特殊含義的字元。
shutil¶
新函式
disk_usage()
: 提供總磁碟空間、已用磁碟空間和可用磁碟空間統計資訊。(由 Giampaolo Rodolà 在 bpo-12442 中貢獻。)chown()
: 允許更改給定路徑的使用者和/或組,也可以指定使用者/組名稱,而不僅僅是其數字 ID。(由 Sandro Tosi 在 bpo-12191 中貢獻。)shutil.get_terminal_size()
: 返回直譯器所連線的終端視窗的大小。(由 Zbigniew Jędrzejewski-Szmek 在 bpo-13609 中貢獻。)
copy2()
和copystat()
現在在支援的平臺上保留納秒級精度的檔案時間戳。它們還在 Linux 上保留檔案“擴充套件屬性”。(由 Larry Hastings 在 bpo-14127 和 bpo-15238 中貢獻。)現在有幾個函式接受可選的
symlinks
引數:當該引數為 true 時,符號連結不會被解引用,而是對符號連結本身執行操作(或者如果相關,則建立一個符號連結)。(由 Hynek Schlawack 在 bpo-12715 中貢獻。)當將檔案複製到不同的檔案系統時,
move()
現在以 posixmv
命令的方式處理符號連結,重新建立符號連結而不是複製目標檔案內容。(由 Jonathan Niehof 在 bpo-9993 中貢獻。)move()
現在還返回dst
引數作為其結果。rmtree()
現在可以抵抗支援os.open()
和os.unlink()
中新的dir_fd
引數的平臺上的符號連結攻擊。(由 Martin von Löwis 和 Hynek Schlawack 在 bpo-4489 中貢獻。)
signal¶
signal
模組有新的函式pthread_sigmask()
: 獲取和/或更改呼叫執行緒的訊號掩碼(由 Jean-Paul Calderone 在 bpo-8407 中貢獻);pthread_kill()
: 向執行緒傳送訊號;sigpending()
: 檢查待處理的函式;sigwait()
: 等待訊號;sigwaitinfo()
: 等待訊號,返回關於訊號的詳細資訊;sigtimedwait()
: 類似於sigwaitinfo()
,但有超時。
訊號處理程式將訊號編號作為單個位元組寫入喚醒檔案描述符,而不是空位元組。因此可以等待多個訊號,並知道引發了哪些訊號。
signal.signal()
和signal.siginterrupt()
引發 OSError,而不是 RuntimeError: OSError 有一個 errno 屬性。
smtpd¶
smtpd
模組現在支援 RFC 5321(擴充套件 SMTP)和 RFC 1870(大小擴充套件)。根據標準,只有當客戶端使用 EHLO
命令啟動會話時,這些擴展才會被啟用。
(最初的 ELHO
支援由 Alberto Trevino 提供。大小擴充套件由 Juhana Jauhiainen 提供。該補丁的大量額外工作由 Michele Orrù 和 Dan Boswell 貢獻。bpo-8739)
smtplib¶
現在,SMTP
、SMTP_SSL
和 LMTP
類接受一個 source_address
關鍵字引數,用於指定在建立傳出套接字時,繫結呼叫中用作源地址的 (主機, 埠)
。(由 Paulo Scardine 在 bpo-11281 中貢獻。)
SMTP
現在支援上下文管理協議,允許在 with
語句中使用 SMTP
例項。(由 Giampaolo Rodolà 在 bpo-11289 中貢獻。)
SMTP_SSL
建構函式和 starttls()
方法現在接受一個 SSLContext 引數,用於控制安全通道的引數。(由 Kasun Herath 在 bpo-8809 中貢獻。)
socket¶
當底層平臺支援時,
socket
類現在公開了額外的處理輔助資料的方法(由 David Watson 在 bpo-6560 中貢獻,基於 Heiko Wundram 之前的補丁)
socket
類現在支援 Linux 上的 PF_CAN 協議族 (https://en.wikipedia.org/wiki/Socketcan, https://lwn.net/Articles/253425)。(由 Matthias Fuchs 貢獻,Tiago Gonçalves 在 bpo-10141 中更新。)
socket
類現在支援 PF_RDS 協議族 (https://en.wikipedia.org/wiki/Reliable_Datagram_Sockets 和 https://oss.oracle.com/projects/rds)。socket
類現在支援 OS X 上的PF_SYSTEM
協議族。(由 Michael Goderbauer 在 bpo-13777 中貢獻。)新的函式
sethostname()
允許在 Unix 系統上設定主機名,如果呼叫程序具有足夠的許可權。(由 Ross Lagerwall 在 bpo-10866 中貢獻。)
socketserver¶
BaseServer
現在有一個可重寫的方法 service_actions()
,該方法由服務迴圈中的 serve_forever()
方法呼叫。ForkingMixIn
現在使用此方法來清理殭屍子程序。(由 Justin Warkentin 在 bpo-11109 中貢獻。)
sqlite3¶
新的 sqlite3.Connection
方法 set_trace_callback()
可用於捕獲 sqlite 處理的所有 sql 命令的跟蹤。(由 Torsten Landschoff 在 bpo-11688 中貢獻。)
ssl¶
ssl
模組有兩個新的隨機生成函式RAND_bytes()
:生成加密強度高的偽隨機位元組。RAND_pseudo_bytes()
:生成偽隨機位元組。
(由 Victor Stinner 在 bpo-12049 中貢獻。)
ssl
模組現在公開了更細粒度的異常層次結構,以便更容易檢查各種型別的錯誤。(由 Antoine Pitrou 在 bpo-11183 中貢獻。)load_cert_chain()
現在接受一個 password 引數,如果私鑰被加密,則使用該引數。(由 Adam Simpkins 在 bpo-12803 中貢獻。)現在透過
load_dh_params()
和set_ecdh_curve()
方法支援常規的 Diffie-Hellman 金鑰交換和基於橢圓曲線的金鑰交換。(由 Antoine Pitrou 在 bpo-13626 和 bpo-13627 中貢獻。)SSL 套接字有一個新的
get_channel_binding()
方法,允許實現某些身份驗證機制,例如 SCRAM-SHA-1-PLUS。(由 Jacek Konieczny 在 bpo-12551 中貢獻。)您可以查詢 SSL 套接字使用的 SSL 壓縮演算法,這要歸功於其新的
compression()
方法。新的屬性OP_NO_COMPRESSION
可用於停用壓縮。(由 Antoine Pitrou 在 bpo-13634 中貢獻。)已使用
ssl.SSLContext.set_npn_protocols()
方法添加了對下一協議協商擴充套件的支援。(由 Colin Marc 在 bpo-14204 中貢獻。)現在,由於
library
和reason
屬性,可以更輕鬆地內省 SSL 錯誤。(由 Antoine Pitrou 在 bpo-14837 中貢獻。)get_server_certificate()
函式現在支援 IPv6。(由 Charles-François Natali 在 bpo-11811 中貢獻。)新的屬性
OP_CIPHER_SERVER_PREFERENCE
允許設定 SSLv3 伺服器套接字以使用伺服器的密碼排序首選項,而不是客戶端的首選項 (bpo-13635)。
stat¶
未文件化的 tarfile.filemode 函式已移至 stat.filemode()
。它可用於將檔案的模式轉換為 ‘-rwxrwxrwx’ 形式的字串。
(由 Giampaolo Rodolà 在 bpo-14807 中貢獻。)
struct¶
struct
模組現在透過新的程式碼 n
和 N
分別支援 ssize_t
和 size_t
。(由 Antoine Pitrou 在 bpo-3163 中貢獻。)
subprocess¶
現在,在 posix 平臺上,命令字串可以是位元組物件。(由 Victor Stinner 在 bpo-8513 中貢獻。)
新的常量 DEVNULL
允許以平臺無關的方式抑制輸出。(由 Ross Lagerwall 在 bpo-5870 中貢獻。)
sys¶
sys
模組有一個新的 thread_info
命名元組,其中包含有關執行緒實現的資訊 (bpo-11223)。
tarfile¶
tarfile
現在透過 lzma
模組支援 lzma
編碼。(由 Lars Gustäbel 在 bpo-5689 中貢獻。)
tempfile¶
tempfile.SpooledTemporaryFile
的 truncate()
方法現在接受一個 size
引數。(由 Ryan Kelly 在 bpo-9957 中貢獻。)
textwrap¶
textwrap
模組有一個新的 indent()
方法,可以輕鬆地在文字塊中的選定行新增通用字首 (bpo-13857)。
threading¶
threading.Condition
、threading.Semaphore
、threading.BoundedSemaphore
、threading.Event
和 threading.Timer
,這些以前都是返回類例項的工廠函式,現在都是類,可以被繼承。(由 Éric Araujo 在 bpo-10968 中貢獻。)
threading.Thread
建構函式現在接受一個 daemon
關鍵字引數,以覆蓋從父執行緒繼承 daemon
標誌值的預設行為 (bpo-6064)。
以前的私有函式 _thread.get_ident
現在作為公共函式 threading.get_ident()
可用。這消除了 stdlib 中對 _thread
模組的直接訪問的幾種情況。使用 _thread.get_ident
的第三方程式碼也應該改為使用新的公共介面。
time¶
get_clock_info()
:獲取有關時鐘的資訊。monotonic()
:單調時鐘(不能後退),不受系統時鐘更新的影響。perf_counter()
:具有最高可用解析度的效能計數器,用於測量短時間間隔。process_time()
:當前程序的系統和使用者 CPU 時間之和。
其他新函式
帶有
CLOCK_xxx
常量的clock_getres()
、clock_gettime()
和clock_settime()
函式。(由 Victor Stinner 在 bpo-10278 中貢獻。)
為了提高跨平臺的一致性,當傳遞負的睡眠值時,sleep()
現在會引發 ValueError
。以前這在 posix 上是一個錯誤,但在 Windows 上會產生無限睡眠。
types¶
新增一個新的 types.MappingProxyType
類:對映的只讀代理。( bpo-14386)
新的函式 types.new_class()
和 types.prepare_class()
為符合 PEP 3115 的動態型別建立提供支援。( bpo-14588)
unittest¶
assertRaises()
、assertRaisesRegex()
、assertWarns()
和 assertWarnsRegex()
現在在用作上下文管理器時接受關鍵字引數 msg。(由 Ezio Melotti 和 Winston Ewert 在 bpo-10775 中貢獻。)
unittest.TestCase.run()
現在返回 TestResult
物件。
urllib¶
Request
類現在接受一個 method 引數,該引數由 get_method()
用於確定應使用哪個 HTTP 方法。例如,這將傳送一個 'HEAD'
請求
>>> urlopen(Request('https://python.club.tw', method='HEAD'))
webbrowser¶
webbrowser
模組支援更多“瀏覽器”:Google Chrome(命名為 chrome、chromium、chrome-browser 或 chromium-browser,具體取決於版本和作業系統)以及來自 FreeDesktop.org 專案的通用啟動器 xdg-open 和 GNOME 3 的預設 URI 處理程式 gvfs-open。(前者由 Arnaud Calmettes 在 bpo-13620 中貢獻,後者由 Matthias Klose 在 bpo-14493 中貢獻。)
xml.etree.ElementTree¶
現在,xml.etree.ElementTree
模組預設匯入其 C 加速器;不再需要顯式匯入 xml.etree.cElementTree
(此模組為了向後相容而保留,但現在已被棄用)。 此外,Element
的 iter
方法系列已得到最佳化 (用 C 重寫)。該模組的文件也得到了極大的改進,增加了示例和更詳細的參考。
zlib¶
新的屬性 zlib.Decompress.eof
可以區分格式正確的壓縮流和不完整或截斷的壓縮流。(由 Nadeem Vawda 在 bpo-12646 中貢獻。)
新的屬性 zlib.ZLIB_RUNTIME_VERSION
報告執行時載入的底層 zlib
庫的版本字串。(由 Torsten Landschoff 在 bpo-12306 中貢獻。)
最佳化¶
添加了主要的效能增強功能
構建和 C API 更改¶
對 Python 的構建過程和 C API 的更改包括
新的 PEP 3118 相關函式
PEP 393 添加了新的 Unicode 型別、宏和函式
高階 API
低階 API
PyUnicode_DATA
,PyUnicode_1BYTE_DATA
,PyUnicode_2BYTE_DATA
,PyUnicode_4BYTE_DATA
PyUnicode_KIND
與PyUnicode_Kind
列舉:PyUnicode_WCHAR_KIND
,PyUnicode_1BYTE_KIND
,PyUnicode_2BYTE_KIND
,PyUnicode_4BYTE_KIND
PyArg_ParseTuple
現在接受bytearray
作為c
格式 (bpo-12380)。
已棄用¶
不支援的作業系統¶
由於缺少維護者,不再支援 OS/2 和 VMS。
由於維護負擔,不再支援 Windows 2000 和將 COMSPEC
設定為 command.com
的 Windows 平臺。
在 3.2 中已棄用的 OSF 支援已完全刪除。
已棄用的 Python 模組、函式和方法¶
將非空字串傳遞給
object.__format__()
已被棄用,並且將在 Python 3.4 中產生TypeError
(bpo-9856)。由於 PEP 393,
unicode_internal
編解碼器已被棄用,請使用 UTF-8、UTF-16 (utf-16-le
或utf-16-be
) 或 UTF-32 (utf-32-le
或utf-32-be
)platform.popen()
:請使用subprocess
模組。 請特別檢查使用 subprocess 模組替換舊函式 部分 (bpo-11377)。bpo-13374:Windows 位元組 API 在
os
模組中已被棄用。 請使用 Unicode 檔名,而不是位元組檔名,這樣就不再依賴 ANSI 內碼表,並支援任何檔名。bpo-13988:
xml.etree.cElementTree
模組已棄用。 加速器會在可用時自動使用。time.clock()
的行為取決於平臺:請根據您的要求,使用新的time.perf_counter()
或time.process_time()
函式來獲得明確的行為。os.stat_float_times()
函式已棄用。abc
模組abc.abstractproperty
已棄用,請改用帶有abc.abstractmethod()
的property
。abc.abstractclassmethod
已棄用,請改用帶有abc.abstractmethod()
的classmethod
。abc.abstractstaticmethod
已棄用,請改用帶有abc.abstractmethod()
的staticmethod
。
-
importlib.abc.SourceLoader.path_mtime()
現在已被棄用,推薦使用importlib.abc.SourceLoader.path_stats()
,因為位元組碼檔案現在儲存了編譯該位元組碼檔案的原始檔的修改時間和大小。
C API 中已棄用的函式和型別¶
Py_UNICODE
已被 PEP 393 棄用,並將在 Python 4 中移除。所有使用此型別的函式都被棄用。
使用 Py_UNICODE
和 Py_UNICODE* 型別的 Unicode 函式和方法
PyUnicode_FromUnicode
: 使用PyUnicode_FromWideChar()
或PyUnicode_FromKindAndData()
PyUnicode_AS_UNICODE
,PyUnicode_AsUnicode()
,PyUnicode_AsUnicodeAndSize()
: 使用PyUnicode_AsWideCharString()
PyUnicode_AS_DATA
: 使用PyUnicode_DATA
以及PyUnicode_READ
和PyUnicode_WRITE
PyUnicode_GET_SIZE
,PyUnicode_GetSize()
: 使用PyUnicode_GET_LENGTH
或PyUnicode_GetLength()
PyUnicode_GET_DATA_SIZE
: 使用PyUnicode_GET_LENGTH(str) * PyUnicode_KIND(str)
(僅適用於已就緒的字串)PyUnicode_AsUnicodeCopy()
: 使用PyUnicode_AsUCS4Copy()
或PyUnicode_AsWideCharString()
PyUnicode_GetMax()
操作 Py_UNICODE* 字串的函式和宏
Py_UNICODE_strlen()
: 使用PyUnicode_GetLength()
或PyUnicode_GET_LENGTH
Py_UNICODE_strcat()
: 使用PyUnicode_CopyCharacters()
或PyUnicode_FromFormat()
Py_UNICODE_strcpy()
,Py_UNICODE_strncpy()
,Py_UNICODE_COPY()
: 使用PyUnicode_CopyCharacters()
或PyUnicode_Substring()
Py_UNICODE_strcmp()
: 使用PyUnicode_Compare()
Py_UNICODE_strncmp()
: 使用PyUnicode_Tailmatch()
Py_UNICODE_strchr()
,Py_UNICODE_strrchr()
: 使用PyUnicode_FindChar()
Py_UNICODE_FILL()
: 使用PyUnicode_Fill()
Py_UNICODE_MATCH
編碼器
PyUnicode_Encode()
: 使用PyUnicode_AsEncodedObject()
PyUnicode_EncodeUTF7()
PyUnicode_EncodeUTF8()
: 使用PyUnicode_AsUTF8()
或PyUnicode_AsUTF8String()
PyUnicode_EncodeUTF32()
PyUnicode_EncodeUTF16()
PyUnicode_EncodeUnicodeEscape()
使用PyUnicode_AsUnicodeEscapeString()
PyUnicode_EncodeRawUnicodeEscape()
使用PyUnicode_AsRawUnicodeEscapeString()
PyUnicode_EncodeLatin1()
: 使用PyUnicode_AsLatin1String()
PyUnicode_EncodeASCII()
: 使用PyUnicode_AsASCIIString()
PyUnicode_EncodeCharmap()
PyUnicode_TranslateCharmap()
PyUnicode_EncodeMBCS()
: 使用PyUnicode_AsMBCSString()
或PyUnicode_EncodeCodePage()
(使用CP_ACP
code_page)PyUnicode_EncodeDecimal()
,PyUnicode_TransformDecimalToASCII()
已棄用的特性¶
array
模組的 'u'
格式程式碼現在已被棄用,並將在 Python 4 中與其餘的 (Py_UNICODE
) API 一起移除。
移植到 Python 3.3¶
本節列出了之前描述的更改和其他可能需要更改程式碼的錯誤修復。
移植 Python 程式碼¶
雜湊隨機化預設啟用。將
PYTHONHASHSEED
環境變數設定為0
以停用雜湊隨機化。另請參閱object.__hash__()
方法。bpo-12326: 在 Linux 上,sys.platform 不再包含主版本號。它現在始終為 ‘linux’,而不是根據用於構建 Python 的 Linux 版本而定的 ‘linux2’ 或 ‘linux3’。將 sys.platform == ‘linux2’ 替換為 sys.platform.startswith(‘linux’),或者如果您不需要支援較舊的 Python 版本,則直接替換為 sys.platform == ‘linux’。
bpo-13847, bpo-14180:
time
和datetime
: 如果時間戳超出範圍,現在會引發OverflowError
錯誤,而不是ValueError
錯誤。如果 C 函式gmtime()
或localtime()
失敗,現在會引發OSError
錯誤。import 使用的預設查詢器現在會快取特定目錄中包含的內容。如果您建立了 Python 原始碼檔案或無原始碼的位元組碼檔案,請務必呼叫
importlib.invalidate_caches()
來清除查詢器的快取,以便查詢器能夠注意到新檔案。ImportError
現在使用嘗試匯入的模組的完整名稱。檢查 ImportErrors 訊息的 doctest 需要更新為使用模組的完整名稱,而不僅僅是名稱的尾部。__import__()
的 *index* 引數現在預設為 0 而不是 -1,並且不再支援負值。在實現 PEP 328 時,預設值仍然為 -1 是一個疏忽。如果您需要繼續執行相對匯入,然後再執行絕對匯入,則可以使用索引 1 執行相對匯入,然後使用索引 0 執行另一次匯入。不過,建議您使用importlib.import_module()
,而不是直接呼叫__import__()
。__import__()
不再允許對頂級模組使用除 0 以外的索引值。例如,__import__('sys', level=1)
現在會報錯。由於
sys.meta_path
和sys.path_hooks
預設情況下現在都有查詢器,您很可能需要使用list.insert()
而不是list.append()
來新增到這些列表中。由於
None
現在被插入到sys.path_importer_cache
中,如果您要清除字典中沒有查詢器的路徑條目,則需要刪除與None
**和**imp.NullImporter
值配對的鍵,以實現向後相容。這將導致在舊版本的 Python 上產生額外的開銷,這些舊版本的 Python 會將None
重新插入到sys.path_importer_cache
中,其中它表示隱式查詢器的使用,但從語義上講,它不應該改變任何內容。importlib.abc.Finder
不再指定必須實現的find_module()
抽象方法。如果您依賴子類來實現該方法,請確保首先檢查該方法是否存在。不過,您可能需要首先檢查find_loader()
,以便在使用 路徑條目查詢器 時正常工作。pkgutil
已轉換為在內部使用importlib
。這消除了許多邊緣情況,在這些情況下,舊的 PEP 302 匯入模擬未能匹配實際匯入系統的行為。匯入模擬本身仍然存在,但現在已棄用。pkgutil.iter_importers()
和pkgutil.walk_packages()
函式特殊處理標準匯入鉤子,因此即使它們不提供非標準的iter_modules()
方法,它們仍然受支援。email.header.decode_header()
所做的解析中存在一個長期的 RFC 合規性錯誤 (bpo-1079) 已修復。使用標準習慣用法將編碼的標頭轉換為 unicode 的程式碼(str(make_header(decode_header(h))
)將看不到任何變化,但是檢視 decode_header 返回的各個元組的程式碼會發現,位於ASCII
部分之前或之後的空格現在包含在ASCII
部分中。使用make_header
構建標頭的程式碼也應該繼續正常工作,因為如果輸入字串中尚不存在,make_header
會繼續在ASCII
和非ASCII
部分之間新增空格。email.utils.formataddr()
現在在傳遞非ASCII
顯示名稱時會執行正確的內容傳輸編碼。任何依賴先前錯誤行為(在格式化輸出字串中保留非ASCII
unicode)的程式碼都需要更改 (bpo-1690608)。poplib.POP3.quit()
現在可能會像所有其他poplib
方法一樣引發協議錯誤。如果特定應用程式遇到quit
上的錯誤,則假設quit
不會引發poplib.error_proto
錯誤的程式碼可能需要更改 (bpo-11291)。自 Python 2.4 起已棄用的
email.parser.Parser
的strict
引數已最終刪除。已刪除已棄用的方法
unittest.TestCase.assertSameElements
。已刪除已棄用的變數
time.accept2dyear
。已從
decimal
模組中刪除已棄用的Context._clamp
屬性。它之前已被公共屬性clamp
替換。(請參閱 bpo-8540。)已從
smtplib
中刪除未記錄的內部輔助類SSLFakeFile
,因為它的功能早已由socket.socket.makefile()
直接提供。現在,在 Windows 上向
time.sleep()
傳遞負值會引發錯誤,而不是永遠休眠。它在 posix 上始終會引發錯誤。已刪除
ast.__version__
常量。如果您需要做出受 AST 版本影響的決策,請使用sys.version_info
來做出決策。透過子類化私有類來解決
threading
模組使用工廠函式的事實的程式碼,將需要更改為子類化現在是公共的類。執行緒模組中未記錄的除錯機制已刪除,從而簡化了程式碼。這應該對生產程式碼沒有影響,但此處提及是為了以防任何應用程式除錯框架與之互動 (bpo-13550)。
移植 C 程式碼¶
在對緩衝區 API 進行更改的過程中,已刪除未記錄的
Py_buffer
結構的smalltable
成員,並且PyMemoryViewObject
的佈局已更改。所有依賴於
memoryobject.h
或object.h
中相關部分的擴充套件都必須重新構建。由於 PEP 393,
Py_UNICODE
型別以及所有使用該型別的函式已被棄用(但至少會保留五年)。如果您之前使用底層 Unicode API 來構造和訪問 Unicode 物件,並且希望利用 PEP 393 提供的記憶體佔用減少的優勢,您必須將程式碼轉換為新的 Unicode API。但是,如果您只使用諸如
PyUnicode_Concat()
、PyUnicode_Join()
或PyUnicode_FromFormat()
之類的高階函式,您的程式碼將自動利用新的 Unicode 表示形式。PyImport_GetMagicNumber()
現在在失敗時返回-1
。由於
__import__()
的 level 引數的負值不再有效,因此PyImport_ImportModuleLevel()
也同樣如此。這也意味著PyImport_ImportModuleEx()
使用的 level 值現在是0
而不是-1
。
構建 C 擴充套件¶
C 擴充套件的可能檔名範圍已縮小。已取消使用很少使用的拼寫:在 POSIX 下,名為
xxxmodule.so
、xxxmodule.abi3.so
和xxxmodule.cpython-*.so
的檔案不再被識別為實現xxx
模組。如果您之前生成過此類檔案,則必須切換到其他拼寫(即,從檔名中刪除module
字串)。(在 bpo-14040 中實現。)