Python 3.3 中的新增功能

本文件解釋了 Python 3.3 相對於 3.2 的新功能。Python 3.3 於 2012 年 9 月 29 日釋出。有關完整詳細資訊,請參閱更新日誌

參見

PEP 398 - Python 3.3 釋出計劃

摘要 – 釋出亮點

新語法功能

  • 新的 yield from 表示式,用於生成器委託

  • 對於 str 物件,再次接受 u'unicode' 語法。

新庫模組

  • faulthandler (有助於除錯低階崩潰)

  • ipaddress (表示 IP 地址和掩碼的高階物件)

  • lzma (使用 XZ / LZMA 演算法壓縮資料)

  • unittest.mock (用 mock 物件替換測試系統的一部分)

  • venv (Python 虛擬環境,如流行的 virtualenv 包)

新的內建功能

實現改進

顯著改進的庫模組

安全改進

  • 雜湊隨機化預設啟用。

請繼續閱讀以獲取使用者可見更改的完整列表。

PEP 405:虛擬環境

虛擬環境有助於在共享系統範圍的基礎安裝的同時建立單獨的 Python 設定,以便於維護。虛擬環境擁有自己的私有 site-packages(即本地安裝的庫),並且可以選擇與系統範圍的 site-packages 分離。它們的理念和實現受到流行的第三方 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 風格陣列的記憶體佈局。

功能

  • 現在支援結構模組語法中所有原生單字元格式說明符(可選字首為“@”)。

  • 在某些限制下,cast() 方法允許更改 C 連續陣列的格式和形狀。

  • 支援任何陣列型別的多維列表表示。

  • 支援任何陣列型別的多維比較。

  • 格式為 B、b 或 c 的可雜湊(只讀)型別的一維記憶體檢視現在可雜湊。(由 Antoine Pitrou 在bpo-13411 中貢獻。)

  • 支援任意一維陣列型別的切片。例如,現在可以透過使用負步長在 O(1) 時間內反轉記憶體檢視。

API 變更

  • 最大維數官方限制為 64。

  • 空形狀、步幅和子偏移量的表示現在是空元組,而不是 None

  • 使用格式 'B'(無符號位元組)訪問 memoryview 元素現在返回一個整數(根據結構模組語法)。要返回位元組物件,必須首先將檢視轉換為 'c'。

  • memoryview 比較現在使用運算元的邏輯結構並按值比較所有陣列元素。支援結構模組語法中的所有格式字串。仍允許使用無法識別的格式字串的檢視,但無論檢視內容如何,它們將始終比較為不相等。

  • 有關進一步更改,請參閱構建和 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+0000U+10FFFF)。窄構建和寬構建之間的區別不再存在,Python 現在表現得像一個寬構建,即使在 Windows 下也是如此。

  • 隨著窄構建的消亡,窄構建特有的問題也得到了修復,例如

    • len() 現在始終對非 BMP 字元返回 1,因此 len('\U0010FFFF') == 1

    • 代理對在字串文字中不再重新組合,因此 '\uDBFF\uDFFF' != '\U0010FFFF'

    • 索引或切片非 BMP 字元返回預期值,因此 '\U0010FFFF'[0] 現在返回 '\U0010FFFF' 而不是 '\uDBFF'

    • 標準庫中的所有其他函式現在都能正確處理非 BMP 碼點。

  • sys.maxunicode 的值現在始終為 1114111(十六進位制為 0x10FFFF)。PyUnicode_GetMax() 函式為了向後相容性仍然返回 0xFFFF0x10FFFF,並且不應與新的 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 基準測試中(詳見 PEP),Python 3.3 的記憶體使用量是 Python 3.2 的兩到三倍小,並且比 Python 2.7 稍好。

參見

PEP 393 - 靈活的字串表示

PEP 由 Martin von Löwis 撰寫;由 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 時請求 Python 3 的 -3,或者當安裝了更新版本時專門請求早期 Python 版本的 -2.6)。

除了啟動器,Windows 安裝程式現在還包含一個選項,可以將新安裝的 Python 新增到系統 PATH。(由 Brian Curtin 在bpo-3561 中貢獻。)

參見

PEP 397 - Windows Python 啟動器

PEP 由 Mark Hammond 和 Martin v. Löwis 撰寫;由 Vinay Sajip 實現。

啟動器文件:Python 安裝管理器

安裝程式 PATH 修改:Python 安裝管理器

PEP 3151:重構作業系統和 IO 異常層次結構

由作業系統錯誤引發的異常層次結構現在既簡化又更細粒度。

您不再需要擔心在 OSErrorIOErrorEnvironmentErrorWindowsErrormmap.errorsocket.errorselect.error 之間選擇適當的異常型別。所有這些異常型別現在都只是一種:OSError。其他名稱仍作為別名保留,以實現相容性。

此外,現在更容易捕獲特定的錯誤情況。您無需檢查 errno 屬性(或 args[0])以獲取 errno 模組中的特定常量,而是可以捕獲適當的 OSError 子類。可用的子類如下

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 - 重構作業系統和 IO 異常層次結構

PEP 由 Antoine Pitrou 撰寫並實現

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]

推動這一變化的主要原則是,即使是設計用於 sendthrow 方法的生成器,也可以像將單個大型函式拆分為多個子函式一樣容易地拆分為多個子生成器。

參見

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 字面量

為了方便 Unicode 敏感的 Python 應用程式從 Python 2 遷移,這些應用程式大量使用 Unicode 字面量,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.Signatureinspect.Parameterinspect.BoundArguments 儲存有關呼叫簽名(例如,註釋、預設值、引數型別和繫結引數)的資訊,這大大簡化了編寫裝飾器和任何驗證或修改呼叫簽名或引數的程式碼。

參見

PEP 362: - 函式簽名物件

PEP 由 Brett Cannon、Yury Selivanov、Larry Hastings、Jiwon Seo 撰寫;由 Yury Selivanov 實現。

PEP 421:新增 sys.implementation

sys 模組上的新屬性公開了當前正在執行的直譯器實現的特定詳細資訊。sys.implementation 的初始屬性集是 nameversionhexversioncache_tag

sys.implementation 的目的是將標準庫使用的實現特定資料合併到一個名稱空間中。這使得不同的 Python 實現更容易共享單個標準庫程式碼庫。在初始狀態下,sys.implementation 只包含一小部分實現特定資料。隨著時間的推移,這個比例會發生變化,以使標準庫更具可移植性。

標準庫可移植性改進的一個例子是 cache_tag。從 Python 3.3 開始,importlib 使用 sys.implementation.cache_tag 來支援 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 VM 提供了一個單一的實現,有助於消除匯入語義中任何 VM 特定的偏差。最後,它簡化了匯入的維護,允許未來的增長。

對於普通使用者來說,語義上應該沒有可見的更改。對於那些當前操縱匯入或以程式設計方式呼叫匯入的程式碼,可能需要的程式碼更改已在本文件的移植 Python 程式碼部分中介紹。

新 API

這項工作的一個巨大好處是揭示了匯入語句的工作原理。這意味著曾經隱式的各種匯入器現在已完全作為 importlib 包的一部分公開。

importlib.abc 中定義的抽象基類已擴充套件,透過引入 importlib.abc.MetaPathFinderimportlib.abc.PathEntryFinder,正確區分了元路徑查詢器路徑入口查詢器。舊的抽象基類 importlib.abc.Finder 現在僅為向後相容性而提供,不強制任何方法要求。

在查詢器方面,importlib.machinery.FileFinder 公開了用於搜尋模組原始檔和位元組碼檔案的機制。以前,這個類是 sys.path_hooks 的隱式成員。

對於載入器,新的抽象基類 importlib.abc.FileLoader 有助於編寫一個使用檔案系統作為模組程式碼儲存機制的載入器。原始檔載入器(importlib.machinery.SourceFileLoader)、無源位元組碼檔案載入器(importlib.machinery.SourcelessFileLoader)和擴充套件模組載入器(importlib.machinery.ExtensionFileLoader)現在可以直接使用。

ImportError 現在具有 namepath 屬性,當有相關資料可提供時會設定這些屬性。匯入失敗的訊息現在也將提供模組的完整名稱,而不僅僅是模組名稱的末尾。

importlib.invalidate_caches() 函式現在將呼叫 sys.path_importer_cache 中所有快取的查詢器上同名的方法,以根據需要幫助清理任何儲存狀態。

可見更改

有關可能需要的程式碼更改,請參閱移植 Python 程式碼一節。

除了 importlib 現在公開的範圍之外,匯入還有其他可見更改。最大的一點是 sys.meta_pathsys.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

  • bytesbytearray 物件的 count()find()rfind()index()rindex() 方法現在接受 0 到 255 之間的整數作為它們的第一個引數。

    (由 Petri Lehtinen 在bpo-12170 中貢獻。)

  • bytesbytearrayrjust()ljust()center() 方法現在接受 bytearray 作為 fill 引數。(由 Petri Lehtinen 在bpo-12380 中貢獻。)

  • listbytearray 中添加了新方法: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 引數:檔案物件的底層檔案描述符透過呼叫 opener 和 (file, flags) 來獲得。它可用於使用自定義標誌,例如 os.O_CLOEXEC。添加了 'x' 模式:以獨佔建立模式開啟,如果檔案已存在則失敗。

  • print():添加了 flush 關鍵字引數。如果 flush 關鍵字引數為 true,則強制重新整理流。

  • hash():雜湊隨機化預設啟用,請參閱 object.__hash__()PYTHONHASHSEED

  • str 型別獲得了一個新的 casefold() 方法:返回字串的大小寫摺疊副本,大小寫摺疊字串可用於不區分大小寫的匹配。例如,'ß'.casefold() 返回 'ss'

  • 序列文件已大幅重寫,以更好地解釋二進位制/文字序列的區別,併為各個內建序列型別提供特定的文件部分(bpo-4966)。

新模組

faulthandler

這個新的除錯模組 faulthandler 包含用於在故障(如段錯誤等崩潰)、超時或使用者訊號時顯式轉儲 Python 追溯的函式。呼叫 faulthandler.enable() 可為 SIGSEGVSIGFPESIGABRTSIGBUSSIGILL 訊號安裝故障處理程式。您也可以透過設定 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__ 作為動態更新的屬性。內建描述符已相應更新。

(由 Darren Dale 在bpo-11610 中貢獻。)

abc.ABCMeta.register() 現在返回註冊的子類,這意味著它現在可以用作類裝飾器(bpo-10868)。

array

array 模組支援使用 qQ 型別程式碼的 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.BZ2Filebz2.decompress() 現在可以解壓縮多流輸入(例如 pbzip2 工具產生的輸入)。bz2.BZ2File 現在也可以使用 'a'(追加)模式建立此類檔案。

    (由 Nir Aides 在bpo-1625 中貢獻。)

  • bz2.BZ2File 現在實現了 io.BufferedIOBase API 的所有功能,除了 detach()truncate() 方法。

codecs

mbcs 編碼器已重寫,以在所有 Windows 版本上正確處理 replaceignore 錯誤處理程式。mbcs 編碼器現在支援所有錯誤處理程式,而不是僅支援 replace 進行編碼和 ignore 進行解碼。

添加了一個新的僅限 Windows 的編碼器:cp65001bpo-13216)。它是 Windows 內碼表 65001 (Windows UTF-8, CP_UTF8)。例如,如果控制檯輸出內碼表設定為 cp65001(例如,使用 chcp 65001 命令),則由 sys.stdout 使用。

多位元組 CJK 解碼器現在重新同步更快。它們只忽略無效位元組序列的第一個位元組。例如,b'\xff\n'.decode('gb2312', 'replace') 現在在替換字元後返回一個 \n

bpo-12016

增量 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.'

bpo-12100

unicode_internal 編碼器已棄用。

collections

添加了一個新的 ChainMap 類,允許將多個對映視為一個單元。(由 Raymond Hettinger 為bpo-11089 編寫,並在bpo-11297 中公開。)

抽象基類已移至新的 collections.abc 模組中,以更好地區分抽象集合類和具體集合類。為保留現有匯入,ABCs 的別名仍存在於 collections 模組中。(bpo-11085

Counter 類現在支援一元運算子 +-,以及就地運算子 +=-=|=&=。(由 Raymond Hettinger 在bpo-13121 中貢獻。)

contextlib

ExitStack 現在為上下文管理器和類似清理功能的程式設計操作提供了堅實的基礎。與以前的 contextlib.nested API(已棄用並刪除)不同,新 API 旨在無論上下文管理器是在其 __init__ 方法(例如檔案物件)中還是在其 __enter__ 方法(例如 threading 模組中的同步物件)中獲取資源,都能正常工作。

bpo-13585

crypt

crypt 模組中增加了 salt 和模組化加密格式(雜湊方法)以及 mksalt() 函式。

bpo-10924

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

decimal

bpo-7652 - 整合快速原生十進位制算術。

C 模組和 libmpdec 由 Stefan Krah 撰寫。

新的十進位制模組的 C 版本集成了高速的 libmpdec 庫,用於任意精度正確舍入的十進位制浮點算術。libmpdec 符合 IBM 的通用十進位制算術規範。

效能提升範圍從資料庫應用程式的 10 倍到數值密集型應用程式的 100 倍。這些數字是十進位制浮點算術中使用的標準精度的預期增益。由於精度是使用者可配置的,因此具體數字可能會有所不同。例如,在整數大數算術中,差異可能顯著更高。

下表僅供說明。基準測試可在 https://www.bytereef.org/mpdecimal/quickstart.html 獲得。

decimal.py

_decimal

加速

pi

42.02 秒

0.345 秒

120 倍

電信

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

  • 在上下文模板(DefaultContextBasicContextExtendedContext)中,EmaxEmin 的量級已更改為 999999

  • decimal.py 中的 Decimal 建構函式不遵守上下文限制,並精確轉換具有任意指數或精度的值。由於 C 版本具有內部限制,因此使用了以下方案:如果可能,精確轉換值,否則引發 InvalidOperation 且結果為 NaN。在後一種情況下,始終可以使用 create_decimal() 來獲取舍入或不精確的值。

  • decimal.py 中的冪函式始終正確舍入。在 C 版本中,它由正確舍入的 exp()ln() 函式定義,但最終結果僅是“幾乎總是正確舍入”。

  • 在 C 版本中,包含訊號的上下文字典是 MutableMapping。出於速度原因,flagstraps 始終指向上下文初始化時使用的同一個 MutableMapping。如果分配了新的訊號字典,flagstraps 將使用新值進行更新,但它們不引用 RHS 字典。

  • 醃製 Context 會產生不同的輸出,以實現 Python 和 C 版本的通用交換格式。

  • Context 建構函式中的引數順序已更改,以匹配 repr() 顯示的順序。

  • quantize() 方法中的 watchexp 引數已棄用。

email

策略框架

email 包現在有一個 policy 框架。Policy 是一個具有多個方法和屬性的物件,用於控制 email 包的行為。Python 3.3 的主要策略是 Compat32 策略,它提供了與 Python 3.2 中 email 包的向後相容性。policy 可以在 email 訊息由 parser 解析時,或建立 Message 物件時,或使用 generator 序列化 email 時指定。除非被覆蓋,傳遞給 parser 的策略將由 parser 建立的所有 Message 物件和子物件繼承。預設情況下,generator 將使用它正在序列化的 Message 物件的策略。預設策略是 compat32

所有 policy 物件實現的最小控制集是

max_line_length

Message 被序列化時,單個行的最大長度(不包括換行符)。預設為 78。

linesep

Message 被序列化時,用於分隔單個行的字元。預設為 \n

cte_type

7bit8bit8bit 僅適用於 Bytes generator,表示在協議允許的情況下(或在原始輸入中存在的情況下)可以使用非 ASCII 字元。

raise_on_defect

導致 parser 在遇到缺陷時引發錯誤,而不是將它們新增到 Message 物件的 defects 列表中。

一個新的策略例項,具有新的設定,是透過策略物件的 clone() 方法建立的。clone 將上述任何控制元件作為關鍵字引數。任何未在呼叫中指定的控制元件都保留其預設值。因此,您可以建立使用 \r\n 換行符的策略,如下所示

mypolicy = compat32.clone(linesep='\r\n')

策略可以使您的應用程式生成所需格式的訊息變得更簡單。您無需記住在所有呼叫 generator 的地方都指定 linesep='\r\n',您可以在設定 parserMessage 使用的策略時指定一次,無論您的程式使用哪個來建立 Message 物件。另一方面,如果您需要生成多種形式的訊息,您仍然可以在相應的 generator 呼叫中指定引數。或者您可以為不同的情況使用自定義策略例項,並在建立 generator 時傳遞這些例項。

帶有新 Header API 的臨時策略

儘管策略框架本身就很有價值,但引入它的主要動機是允許建立新策略,以一種為不使用新策略的人保持向後相容性的方式實現 email 包的新功能。由於新策略引入了新的 API,我們將在 Python 3.3 中將其作為臨時策略釋出。如果核心開發人員認為有必要,可能會發生向後不相容的更改(包括程式碼的刪除)。

新策略是 EmailPolicy 的例項,並添加了以下附加控制

refold_source

控制由 parser 解析的頭部是否由 generator 重摺疊。它可以是 nonelongall。預設是 long,這意味著長度超過 max_line_length 的源頭部會被重摺疊。none 意味著沒有行被重摺疊,all 意味著所有行都被重摺疊。

header_factory

一個可呼叫物件,它接受一個 namevalue 並生成一個自定義頭部物件。

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>'

解析訊息時,您可以使用頭部物件的 addressesgroups 屬性來訪問組和單個地址

>>> 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 字串,email 包透明地將 unicode 編碼和解碼為 RFC 標準內容傳輸編碼。

其他 API 更改

新的 BytesHeaderParser,新增到 parser 模組中,以補充 HeaderParser 並完成 Bytes API。

新的實用函式

ftplib

  • ftplib.FTP 現在接受 source_address 關鍵字引數,用於在建立傳出套接字時指定 (host, port) 作為 bind 呼叫的源地址。(由 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-14538bpo-13993bpo-13960bpo-13358bpo-1745761bpo-755670bpo-13357bpo-12629bpo-1200313bpo-670664bpo-13273bpo-12888bpo-7311 中貢獻。)

一個新的 html5 字典已新增到 html.entities 模組中,它將 HTML5 命名字元引用對映到等效的 Unicode 字元(例如 html5['gt;'] == '>')。現在 HTMLParser 也使用該字典。(由 Ezio Melotti 在 bpo-11113bpo-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 ‘x’ 模式到 fopen()。

(由 David Townshend 在 bpo-12760 中貢獻。)

TextIOWrapper 類的建構函式有一個新的可選引數 write_through。如果 write_throughTrue,則對 write() 的呼叫保證不會被緩衝:寫入 TextIOWrapper 物件的任何資料都會立即處理到其底層的二進位制緩衝區。

itertools

accumulate() 現在接受一個可選的 func 引數,用於提供使用者提供的二進位制函式。

logging

basicConfig() 函式現在支援一個可選的 handlers 引數,該引數接受一個可迭代的處理程式,用於新增到根記錄器。

已在 SysLogHandler 中添加了一個類級別屬性 append_nul,以允許控制 NUL (\000) 位元組是否附加到 syslog 記錄中,因為有些守護程序需要它,而有些則將其直接傳遞到日誌中。

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.Connection 物件現在可以透過多程序連線進行傳輸。(由 Richard Oudkerk 在 bpo-4892 中貢獻。)

multiprocessing.Process 現在接受一個 daemon 關鍵字引數,以覆蓋從父程序繼承 daemon 標誌的預設行為(bpo-6064)。

新的屬性 multiprocessing.Process.sentinel 允許程式使用適當的作業系統原語(例如,posix 系統上的 select)同時等待多個 Process 物件。

新的方法 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

pdb

現在,Tab 補全不僅適用於命令名稱,也適用於其引數。例如,對於 break 命令,函式和檔名都可以補全。

(由 Georg Brandl 在 bpo-14210 中貢獻)

pickle

pickle.Pickler 物件現在有一個可選的 dispatch_table 屬性,允許設定每個 pickler 的縮減函式。

(由 Richard Oudkerk 在 bpo-14166 中貢獻。)

pydoc

Tk GUI 和 serve() 函式已從 pydoc 模組中移除:pydoc -gserve() 已在 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 類建構函式的 timefuncdelayfunct 引數現在是可選的,分別預設為 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-14127bpo-15238 中貢獻。)

  • 現在有幾個函式接受可選的 symlinks 引數:當該引數為 True 時,符號連結不會被解除引用,而是對符號連結本身執行操作(如果相關,則建立一個)。(由 Hynek Schlawack 在 bpo-12715 中貢獻。)

  • 將檔案複製到不同的檔案系統時,move() 現在像 posix mv 命令那樣處理符號連結,重新建立符號連結而不是複製目標檔案內容。(由 Jonathan Niehof 在 bpo-9993 中貢獻。) move() 現在也將其結果返回為 dst 引數。

  • rmtree() 現在對支援 os.open()os.unlink() 中新 dir_fd 引數的平臺上的符號連結攻擊具有抵抗力。(由 Martin von Löwis 和 Hynek Schlawack 在 bpo-4489 中貢獻。)

訊號

smtpd

smtpd 模組現在支援 RFC 5321(擴充套件 SMTP)和 RFC 1870(大小擴充套件)。根據標準,這些擴充套件僅在客戶端使用 EHLO 命令啟動會話時才啟用。

(初始 ELHO 支援由 Alberto Trevino 貢獻。大小擴充套件由 Juhana Jauhiainen 貢獻。補丁的實質性額外工作由 Michele Orrù 和 Dan Boswell 貢獻。 bpo-8739

smtplib

SMTPSMTP_SSLLMTP 類現在接受 source_address 關鍵字引數,用於在創建出站套接字時在繫結呼叫中指定用作源地址的 (host, port)。(由 Paulo Scardine 在 bpo-11281 中貢獻。)

SMTP 現在支援上下文管理協議,允許在 with 語句中使用 SMTP 例項。(由 Giampaolo Rodolà 在 bpo-11289 中貢獻。)

SMTP_SSL 建構函式和 starttls() 方法現在接受 SSLContext 引數來控制安全通道的引數。(由 Kasun Herath 在 bpo-8809 中貢獻。)

socket

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-13626bpo-13627 中貢獻。)

  • SSL 套接字有一個新的 get_channel_binding() 方法,允許實現某些身份驗證機制,例如 SCRAM-SHA-1-PLUS。(由 Jacek Konieczny 在 bpo-12551 中貢獻。)

  • 您可以透過 SSL 套接字的新 compression() 方法查詢 SSL 套接字使用的 SSL 壓縮演算法。新屬性 OP_NO_COMPRESSION 可用於停用壓縮。(由 Antoine Pitrou 在 bpo-13634 中貢獻。)

  • 已新增對使用 ssl.SSLContext.set_npn_protocols() 方法的下一協議協商擴充套件的支援。(由 Colin Marc 在 bpo-14204 中貢獻。)

  • 由於 libraryreason 屬性,現在可以更輕鬆地檢查 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 模組現在透過新程式碼 nN 分別支援 ssize_tsize_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.SpooledTemporaryFiletruncate() 方法現在接受 size 引數。(由 Ryan Kelly 在 bpo-9957 中貢獻。)

textwrap

textwrap 模組有一個新的 indent() 函式,可以方便地為文字塊中選定的行新增通用字首(bpo-13857)。

threading

threading.Conditionthreading.Semaphorethreading.BoundedSemaphorethreading.Eventthreading.Timer,所有這些曾經是返回類例項的工廠函式,現在都是類並且可以被子類化。(由 Éric Araujo 在 bpo-10968 中貢獻。)

threading.Thread 建構函式現在接受 daemon 關鍵字引數,以覆蓋從父執行緒繼承 daemon 標誌值的預設行為(bpo-6064)。

以前的私有函式 _thread.get_ident 現在作為公共函式 threading.get_ident() 可用。這消除了 stdlib 中對 _thread 模組的幾個直接訪問情況。使用 _thread.get_ident 的第三方程式碼也應更改為使用新的公共介面。

時間

PEP 418time 模組中添加了新函式

  • get_clock_info():獲取時鐘資訊。

  • monotonic():單調時鐘(不能倒退),不受系統時鐘更新影響。

  • perf_counter():具有最高可用解析度的效能計數器,用於測量短持續時間。

  • process_time():當前程序的系統和使用者 CPU 時間的總和。

其他新函式

為了提高跨平臺的一致性,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'))

bpo-1673007

webbrowser

webbrowser 模組支援更多“瀏覽器”:Google Chrome(根據版本和作業系統命名為 chromechromiumchrome-browserchromium-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(此模組出於向後相容性而保留,但現在已棄用)。此外,Elementiter 系列方法已得到最佳化(用 C 重寫)。該模組的文件也得到了極大改進,增加了示例和更詳細的參考。

zlib

新屬性 zlib.Decompress.eof 使區分格式正確的壓縮流和不完整或截斷的壓縮流成為可能。(由 Nadeem Vawda 在 bpo-12646 中貢獻。)

新屬性 zlib.ZLIB_RUNTIME_VERSION 報告執行時載入的底層 zlib 庫的版本字串。(由 Torsten Landschoff 在 bpo-12306 中貢獻。)

最佳化

已新增主要的效能增強

  • 由於 PEP 393,對 Unicode 字串的一些操作已得到最佳化

    • 記憶體佔用根據文字減少 2 到 4 倍

    • 將 ASCII 字串編碼為 UTF-8 不再需要編碼字元,UTF-8 表示與 ASCII 表示共享

    • UTF-8 編碼器已最佳化

    • 重複單個 ASCII 字母並獲取 ASCII 字串的子字串快 4 倍

  • UTF-8 現在快 2 到 4 倍。UTF-16 編碼現在快達 10 倍。

    (由 Serhiy Storchaka 貢獻,bpo-14624bpo-14738bpo-15026。)

構建和 C API 更改

Python 的構建過程和 C API 的更改包括

已棄用

不支援的作業系統

由於缺乏維護者,不再支援 OS/2 和 VMS。

由於維護負擔,不再支援 Windows 2000 和將 COMSPEC 設定為 command.com 的 Windows 平臺。

OSF 支援已在 3.2 中棄用,現已完全刪除。

已棄用的 Python 模組、函式和方法

已棄用的 C API 函式和型別

Py_UNICODE 已被 PEP 393 棄用,並將在 Python 4 中刪除。所有使用此型別的函式均已棄用

使用 Py_UNICODEPy_UNICODE* 型別的 Unicode 函式和方法

操縱 Py_UNICODE* 字串的函式和宏

編碼器

已棄用的功能

array 模組的 'u' 格式程式碼現在已棄用,並將在 Python 4 中與其餘(Py_UNICODE)API 一起刪除。

移植到 Python 3.3

本節列出了前面描述過的變更以及其他可能需要修改程式碼的 bug 修復。

移植 Python 程式碼

  • 雜湊隨機化預設啟用。將 PYTHONHASHSEED 環境變數設定為 0 以停用雜湊隨機化。另請參閱 object.__hash__() 方法。

  • bpo-12326:在 Linux 上,sys.platform 不再包含主版本。它現在始終是 'linux',而不是 'linux2' 或 'linux3',具體取決於用於構建 Python 的 Linux 版本。將 sys.platform == 'linux2' 替換為 sys.platform.startswith('linux'),或者如果您不需要支援舊版 Python,則直接使用 sys.platform == 'linux'。

  • bpo-13847bpo-14180timedatetime:如果時間戳超出範圍,現在會引發 OverflowError 而不是 ValueError。如果 C 函式 gmtime()localtime() 失敗,現在會引發 OSError

  • import 使用的預設查詢器現在利用了特定目錄中包含內容的快取。如果您建立 Python 原始檔或無源位元組碼檔案,請務必呼叫 importlib.invalidate_caches() 以清除查詢器的快取,以便它們注意到新檔案。

  • ImportError 現在使用嘗試匯入的模組的完整名稱。檢查 ImportError 訊息的 doctest 將需要更新為使用模組的完整名稱,而不僅僅是名稱的尾部。

  • __import__()index 引數現在預設為 0 而不是 -1,並且不再支援負值。這是在實現 PEP 328 時的一個疏忽,預設值仍為 -1。如果您需要繼續執行相對匯入,然後執行絕對匯入,則使用索引 1 執行相對匯入,然後使用索引 0 執行另一個匯入。但是,建議您使用 importlib.import_module(),而不是直接呼叫 __import__()

  • __import__() 不再允許對頂級模組使用除 0 以外的索引值。例如,__import__('sys', level=1) 現在是一個錯誤。

  • 由於 sys.meta_pathsys.path_hooks 預設帶有查詢器,您很可能希望使用 list.insert() 而不是 list.append() 將元素新增到這些列表中。

  • 由於 None 現在已插入 sys.path_importer_cache 中,如果您正在清除字典中沒有查詢器的路徑條目,您將需要刪除與 None imp.NullImporter 值配對的鍵,以實現向後相容。這將在舊版 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.Parserstrict 引數最終已被刪除。

  • 已棄用的方法 unittest.TestCase.assertSameElements 已刪除。

  • 已棄用的變數 time.accept2dyear 已刪除。

  • Context._clamp 屬性已從 decimal 模組中刪除。它以前已被公共屬性 clamp 替換。(參見 bpo-8540。)

  • 未文件化的內部幫助程式類 SSLFakeFile 已從 smtplib 中刪除,因為其功能長期以來已由 socket.socket.makefile() 直接提供。

  • 在 Windows 上向 time.sleep() 傳遞負值現在會引發錯誤,而不是永遠休眠。在 posix 上,它一直會引發錯誤。

  • ast.__version__ 常量已刪除。如果您需要根據 AST 版本做出決策,請使用 sys.version_info 來做出決策。

  • 以前透過子類化私有類來解決 threading 模組使用工廠函式的事實的程式碼將需要更改為子類化現在公開的類。

  • threading 模組中未文件化的除錯機制已被刪除,從而簡化了程式碼。這應該不會對生產程式碼產生影響,但在此提及,以防任何應用程式除錯框架與它進行互動(bpo-13550)。

移植 C 程式碼

  • 在緩衝區 API 更改的過程中,Py_buffer 結構體中未文件化的 smalltable 成員已刪除,並且 PyMemoryViewObject 的佈局已更改。

    所有依賴 memoryobject.hobject.h 中相關部分的擴充套件都必須重建。

  • 由於 PEP 393Py_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.soxxxmodule.abi3.soxxxmodule.cpython-*.so 的檔案不再被識別為實現 xxx 模組。如果您一直在生成此類檔案,則必須切換到其他拼寫(即,從檔名中刪除 module 字串)。

    (在 bpo-14040 中實現。)

命令列開關更改

  • -Q 命令列標誌和相關遺留物已刪除。檢查 sys.flags.division_warning 的程式碼需要更新。

    bpo-10998,由 Éric Araujo 貢獻。)

  • python-S 啟動時,import site 將不再向模組搜尋路徑新增特定於站點的路徑。在以前的版本中,它會新增。

    bpo-11591,由 Carl Meyer 貢獻,Éric Araujo 編輯。)