Python 3.7 的新特性

編輯:

Elvis Pranskevichus <elvis@magic.io>

本文解釋了 Python 3.7 相較於 3.6 的新特性。Python 3.7 於 2018 年 6 月 27 日釋出。有關詳細資訊,請參閱變更日誌

摘要 – 版本亮點

新的語法特性

  • PEP 563,推遲型別註解的求值。

向後不相容的語法更改

新的庫模組

新的內建特性

Python 資料模型改進

  • PEP 562,自定義模組屬性訪問。

  • PEP 560,為 typing 模組和泛型型別提供核心支援。

  • dict 物件的插入順序保留特性已被宣告為 Python 語言規範的官方組成部分。

標準庫的重大改進

CPython 實現改進

C API 改進

  • PEP 539,用於執行緒區域性儲存的新 C API

文件改進

此版本在許多方面都有顯著的效能改進。最佳化 部分詳細列出了它們。

有關可能影響與以前 Python 版本相容性的更改列表,請參閱移植到 Python 3.7 部分。

新特性

PEP 563: 推遲求值註解

Python 中型別提示的出現暴露了PEP 3107 中新增並在 PEP 526 中進一步完善的註解功能存在的兩個明顯的可用性問題

  • 註解只能使用當前作用域中已有的名稱,換句話說,它們不支援任何型別的前向引用;並且

  • 註釋原始碼會對 Python 程式的啟動時間產生不利影響。

透過推遲對註解的求值,可以解決這兩個問題。編譯器不會在定義時編譯執行註解中表達式的程式碼,而是將註解以字串形式儲存,該字串形式等效於相關表示式的 AST。如果需要,可以使用 typing.get_type_hints() 在執行時解析註解。在不需要此操作的常見情況下,註解的儲存成本更低(因為短字串會被直譯器駐留),並使啟動時間更快。

在可用性方面,註解現在支援前向引用,使以下語法有效

class C:
    @classmethod
    def from_string(cls, source: str) -> C:
        ...

    def validate_b(self, obj: B) -> bool:
        ...

class B:
    ...

由於此更改會破壞相容性,因此需要在 Python 3.7 中使用 __future__ 匯入在每個模組的基礎上啟用新行為

from __future__ import annotations

它將在 Python 3.10 中成為預設行為。

另請參閱

PEP 563 – 推遲對註解的求值

由 Łukasz Langa 編寫和實現的 PEP。

PEP 538:傳統 C 區域設定強制轉換

在 Python 3 系列中,一個持續存在的挑戰是如何確定一個合理的預設策略,來處理在非 Windows 平臺上使用預設 C 或 POSIX 區域設定時,當前隱含的 “7 位 ASCII” 文字編碼假設。

PEP 538 更新了預設直譯器命令列介面,以自動將該區域設定強制轉換為可用的基於 UTF-8 的區域設定,如新的 PYTHONCOERCECLOCALE 環境變數的文件中所述。以這種方式自動設定 LC_CTYPE 意味著核心直譯器和了解區域設定的 C 擴充套件(例如 readline)都將假設使用 UTF-8 作為預設文字編碼,而不是 ASCII。

PEP 11 中的平臺支援定義也已更新,以將完整的文字處理支援限制為適當配置的非 ASCII 基於區域設定。

作為此更改的一部分,當使用任何定義的強制轉換目標區域設定(當前為 C.UTF-8C.utf8UTF-8)時,stdinstdout 的預設錯誤處理程式現在是 surrogateescape(而不是 strict)。無論區域設定如何,stderr 的預設錯誤處理程式仍然是 backslashreplace

區域設定強制轉換預設是靜默的,但為了幫助除錯可能與區域設定相關的整合問題,可以透過設定 PYTHONCOERCECLOCALE=warn 來請求顯式警告(直接在 stderr 上發出)。如果核心直譯器初始化時,舊的 C 區域設定仍然處於活動狀態,此設定還會導致 Python 執行時發出警告。

雖然 PEP 538 的區域設定強制轉換的優點是也會影響擴充套件模組(例如 GNU readline),以及子程序(包括執行非 Python 應用程式和舊版本 Python 的程序),但它的缺點是需要正在執行的系統上存在合適的目標區域設定。為了更好地處理沒有合適的目標區域設定的情況(例如在 RHEL/CentOS 7 上發生的情況),Python 3.7 還實現了 PEP 540:強制 UTF-8 執行時模式

另請參閱

PEP 538 – 將傳統的 C 區域設定強制轉換為基於 UTF-8 的區域設定

PEP 由 Nick Coghlan 編寫和實現。

PEP 540:強制 UTF-8 執行時模式

新的 -X utf8 命令列選項和 PYTHONUTF8 環境變數可用於啟用 Python UTF-8 模式

在 UTF-8 模式下,CPython 會忽略區域設定,並預設使用 UTF-8 編碼。sys.stdinsys.stdout 流的錯誤處理程式設定為 surrogateescape

強制 UTF-8 模式可用於更改嵌入式 Python 直譯器中的文字處理行為,而無需更改嵌入式應用程式的區域設定。

雖然 PEP 540 的 UTF-8 模式的優點是不管執行系統上可用的區域設定如何,它都能正常工作,但它的缺點是對擴充套件模組(例如 GNU readline)、執行非 Python 應用程式的子程序以及執行舊版本 Python 的子程序沒有影響。為了減少與此類元件通訊時損壞文字資料的風險,Python 3.7 還實現了 PEP 540:強制 UTF-8 執行時模式)。

當區域設定為 CPOSIX,並且 PEP 538 區域設定強制轉換功能未能將其更改為基於 UTF-8 的替代項時(無論該失敗是由於設定了 PYTHONCOERCECLOCALE=0,設定了 LC_ALL,還是缺乏合適的目標區域設定),預設啟用 UTF-8 模式。

另請參閱

PEP 540 – 新增新的 UTF-8 模式

PEP 由 Victor Stinner 編寫和實現

PEP 553:內建 breakpoint()

Python 3.7 包括新的內建 breakpoint() 函式,作為進入 Python 偵錯程式的簡單且一致的方式。

內建的 breakpoint() 呼叫 sys.breakpointhook()。預設情況下,後者匯入 pdb,然後呼叫 pdb.set_trace(),但是透過將 sys.breakpointhook() 繫結到您選擇的函式,breakpoint() 可以進入任何偵錯程式。此外,可以將環境變數 PYTHONBREAKPOINT 設定為您選擇的偵錯程式的可呼叫物件。設定 PYTHONBREAKPOINT=0 以完全停用內建的 breakpoint()

另請參閱

PEP 553 – 內建 breakpoint()

PEP 由 Barry Warsaw 編寫和實現

PEP 539:執行緒區域性儲存的新 C API

雖然 Python 為執行緒區域性儲存支援提供了 C API;現有的 執行緒區域性儲存 (TLS) API 使用 int 來表示所有平臺上的 TLS 金鑰。這對於官方支援的平臺來說通常不是問題,但這既不符合 POSIX 標準,也不具有任何實際意義的可移植性。

PEP 539 透過為 CPython 提供新的 執行緒特定儲存 (TSS) API 來改變這一點,該 API 取代了 CPython 直譯器中現有 TLS API 的使用,同時棄用了現有 API。TSS API 使用新的型別 Py_tss_t 而不是 int 來表示 TSS 金鑰,這是一種不透明的型別,其定義可能取決於底層的 TLS 實現。因此,這將允許在原生 TLS 金鑰的定義方式無法安全地轉換為 int 的平臺上構建 CPython。

請注意,在原生 TLS 金鑰的定義方式無法安全地轉換為 int 的平臺上,現有 TLS API 的所有函式都將是空操作並立即返回失敗。這清楚地表明舊的 API 不支援在無法可靠使用的平臺上,並且不會努力新增此類支援。

另請參閱

PEP 539 – CPython 中用於執行緒區域性儲存的新 C-API

PEP 由 Erik M. Bray 編寫;由 Masayuki Yamamoto 實現。

PEP 562:模組屬性訪問的自定義

Python 3.7 允許在模組上定義 __getattr__(),並且當找不到模組屬性時會呼叫它。現在也允許在模組上定義 __dir__()

一個典型的應用場景是模組屬性的棄用和延遲載入。

另請參閱

PEP 562 – 模組 __getattr____dir__

由 Ivan Levkivskyi 編寫和實現的 PEP

PEP 564:具有納秒級解析度的新時間函式

現代系統中時鐘的解析度可能超過 time.time() 函式及其變體返回的浮點數的有限精度。為了避免精度損失,PEP 564time 模組添加了六個新的“納秒”變體的時間函式

新函式將納秒數作為整數值返回。

測量結果 表明,在 Linux 和 Windows 上,time.time_ns() 的解析度大約比 time.time() 高 3 倍。

另請參閱

PEP 564 – 新增具有納秒解析度的新時間函式

PEP 由 Victor Stinner 編寫和實現

PEP 565:在 __main__ 中顯示 DeprecationWarning

DeprecationWarning 的預設處理方式已更改,以便再次預設顯示這些警告,但僅當觸發它們的程式碼直接在 __main__ 模組中執行時。因此,單檔案指令碼的開發者和以互動方式使用 Python 的開發者應該再次開始看到他們使用的 API 的棄用警告,但是由匯入的應用程式、庫和框架模組觸發的棄用警告將繼續預設隱藏。

由於此更改,標準庫現在允許開發者在三種不同的棄用警告行為之間進行選擇

  • FutureWarning:預設情況下始終顯示,建議用於希望應用程式終端使用者看到的警告(例如,針對已棄用的應用程式配置設定)。

  • DeprecationWarning:預設情況下僅在 __main__ 中和執行測試時顯示,建議用於希望其他 Python 開發者看到的警告,其中版本升級可能會導致行為更改或錯誤。

  • PendingDeprecationWarning:預設情況下僅在執行測試時顯示,適用於未來版本升級會將警告類別更改為 DeprecationWarningFutureWarning 的情況。

以前,DeprecationWarningPendingDeprecationWarning 僅在執行測試時可見,這意味著主要編寫單檔案指令碼或以互動方式使用 Python 的開發者可能會對他們使用的 API 中的破壞性更改感到驚訝。

另請參閱

PEP 565 – 在 __main__ 中顯示 DeprecationWarning

由 Nick Coghlan 編寫和實現的 PEP

PEP 560:對 typing 模組和泛型型別的核心支援

最初 PEP 484 的設計方式是不會對核心 CPython 直譯器引入任何更改。現在,型別提示和 typing 模組已被社群廣泛使用,因此取消了此限制。PEP 引入了兩個特殊方法 __class_getitem__()__mro_entries__,這些方法現在被 typing 中的大多數類和特殊構造所使用。因此,型別相關的各種操作速度提高了 7 倍,泛型型別可以在沒有元類衝突的情況下使用,並且修復了 typing 模組中的幾個長期存在的錯誤。

另請參閱

PEP 560 – 對 typing 模組和泛型型別的核心支援

由 Ivan Levkivskyi 編寫和實現的 PEP

PEP 552:基於雜湊的 .pyc 檔案

Python 傳統上透過將原始碼元資料(最後修改的時間戳和大小)與生成時儲存在快取檔案頭中的原始碼元資料進行比較來檢查位元組碼快取檔案(即 .pyc 檔案)的最新程度。雖然有效,但這種失效方法有其缺點。當檔案系統時間戳太粗糙時,Python 可能會錯過原始碼更新,從而導致使用者困惑。此外,在快取檔案中包含時間戳對於構建可重現性和基於內容的構建系統來說是有問題的。

PEP 552 擴充套件了 pyc 格式,允許使用原始檔的雜湊值而不是源時間戳來執行失效。這種 .pyc 檔案稱為“基於雜湊的”。預設情況下,Python 仍然使用基於時間戳的失效,並且不會在執行時生成基於雜湊的 .pyc 檔案。基於雜湊的 .pyc 檔案可以使用 py_compilecompileall 生成。

基於雜湊的 .pyc 檔案有兩種變體:已檢查的和未檢查的。Python 在執行時會根據相應的原始檔驗證已檢查的基於雜湊的 .pyc 檔案,但不會對未檢查的基於雜湊的 pyc 檔案執行此操作。對於 Python 外部的系統(例如,構建系統)負責保持 .pyc 檔案最新的環境,未檢查的基於雜湊的 .pyc 檔案是一種有用的效能最佳化。

有關更多資訊,請參見 快取位元組碼失效

另請參閱

PEP 552 – 確定性的 pyc

由 Benjamin Peterson 編寫和實現的 PEP

PEP 545:Python 文件翻譯

PEP 545 描述了建立和維護 Python 文件翻譯的過程。

已新增三個新的翻譯版本

另請參閱

PEP 545 – Python 文件翻譯

由 Julien Palard、Inada Naoki 和 Victor Stinner 編寫和實現的 PEP。

Python 開發模式 (-X dev)

新的 -X dev 命令列選項或新的 PYTHONDEVMODE 環境變數可用於啟用 Python 開發模式。在開發模式下,Python 執行預設情況下啟用過於昂貴的額外執行時檢查。有關完整說明,請參見 Python 開發模式 文件。

其他語言變更

  • 由於實現上的問題,在await表示式和包含async for子句的推導式在格式化字串字面值中的表示式中是非法的。在 Python 3.7 中,此限制被取消。

  • 現在可以向函式傳遞超過 255 個引數,並且函式現在可以擁有超過 255 個引數。(由 Serhiy Storchaka 在 bpo-12844bpo-18896 中貢獻。)

  • bytes.fromhex()bytearray.fromhex() 現在忽略所有 ASCII 空白字元,而不僅僅是空格。(由 Robert Xiao 在 bpo-28927 中貢獻。)

  • strbytesbytearray 新增了對新的 isascii() 方法的支援,該方法可用於測試字串或位元組是否僅包含 ASCII 字元。(由 INADA Naoki 在 bpo-32677 中貢獻。)

  • from ... import ... 失敗時,ImportError 現在會顯示模組名稱和模組的 __file__ 路徑。(由 Matthias Bussonnier 在 bpo-29546 中貢獻。)

  • 現在支援涉及將子模組繫結到名稱的絕對匯入的迴圈匯入。(由 Serhiy Storchaka 在 bpo-30024 中貢獻。)

  • object.__format__(x, '') 現在等效於 str(x) 而不是 format(str(self), '')。(由 Serhiy Storchaka 在 bpo-28974 中貢獻。)

  • 為了更好地支援動態建立堆疊跟蹤,現在可以從 Python 程式碼例項化 types.TracebackType,並且tb_next屬性現在是可寫的。(由 Nathaniel J. Smith 在 bpo-30579 中貢獻。)

  • 當使用 -m 開關時,sys.path[0] 現在會被立即擴充套件到完整的起始目錄路徑,而不是保留為空目錄(這允許在發生匯入時從*當前*工作目錄進行匯入)(由 Nick Coghlan 在 bpo-33053 中貢獻。)

  • 新的 -X importtime 選項或 PYTHONPROFILEIMPORTTIME 環境變數可用於顯示每個模組匯入的計時。(由 Inada Naoki 在 bpo-31415 中貢獻。)

新模組

contextvars

新的 contextvars 模組和一組 新的 C API 引入了對*上下文變數*的支援。上下文變數在概念上類似於執行緒區域性變數。與 TLS 不同,上下文變數可以正確地支援非同步程式碼。

asynciodecimal 模組已更新,可以開箱即用地使用和支援上下文變數。特別是,活動的十進位制上下文現在儲存在上下文變數中,這使得十進位制運算可以在非同步程式碼中使用正確的上下文。

另請參閱

PEP 567 – 上下文變數

由 Yury Selivanov 編寫和實現的 PEP

dataclasses

新的 dataclass() 裝飾器提供了一種宣告*資料類*的方法。資料類使用類變數註解描述其屬性。其建構函式和其他魔術方法(如 __repr__()__eq__()__hash__())會自動生成。

示例

@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0

p = Point(1.5, 2.5)
print(p)   # produces "Point(x=1.5, y=2.5, z=0.0)"

另請參閱

PEP 557 – 資料類

由 Eric V. Smith 編寫和實現的 PEP

importlib.resources

新的 importlib.resources 模組提供了幾個新的 API 和一個新的 ABC,用於訪問、開啟和讀取包內的*資源*。資源大致類似於包內的檔案,但它們不必是物理檔案系統上的實際檔案。模組載入器可以提供一個 get_resource_reader() 函式,該函式返回一個 importlib.abc.ResourceReader 例項來支援這個新的 API。內建的檔案路徑載入器和 zip 檔案載入器都支援此功能。

由 Barry Warsaw 和 Brett Cannon 在 bpo-32248 中貢獻。

另請參閱

importlib_resources – 適用於早期 Python 版本的 PyPI 向後移植。

改進的模組

argparse

新的 ArgumentParser.parse_intermixed_args() 方法允許混合使用選項和位置引數。(由 paul.j3 在 bpo-14191 中貢獻。)

asyncio

asyncio 模組收到了許多新功能、可用性以及 效能改進。值得注意的變化包括

幾個 asyncio API 已棄用

binascii

b2a_uu() 函式現在接受一個可選的 *backtick* 關鍵字引數。當它為 true 時,零將用 '`' 而不是空格表示。(由 Xiang Zhang 在 bpo-30103 中貢獻。)

calendar

HTMLCalendar 類具有新的類屬性,可簡化生成的 HTML 日曆中 CSS 類的自定義。(由 Oz Tiram 在 bpo-30095 中貢獻。)

collections

collections.namedtuple() 現在支援預設值。(由 Raymond Hettinger 在 bpo-32320 中貢獻。)

compileall

compileall.compile_dir() 學習了新的 *invalidation_mode* 引數,可用於啟用基於雜湊的 .pyc 失效。失效模式也可以使用新的 --invalidation-mode 引數在命令列中指定。(由 Benjamin Peterson 在bpo-31650 中貢獻。)

concurrent.futures

ProcessPoolExecutorThreadPoolExecutor 現在支援新的 *initializer* 和 *initargs* 建構函式引數。(由 Antoine Pitrou 在 bpo-21423 中貢獻。)

ProcessPoolExecutor 現在可以透過新的 *mp_context* 引數獲取多程序上下文。(由 Thomas Moreau 在 bpo-31540 中貢獻。)

contextlib

新的 nullcontext() 是比 ExitStack 更簡單、更快的空操作上下文管理器。(由 Jesse-Bakker 在 bpo-10049 中貢獻。)

新的 asynccontextmanager()AbstractAsyncContextManagerAsyncExitStack 已被新增以補充其同步對應項。(由 Jelle Zijlstra 在 bpo-29679bpo-30241 中貢獻,由 Alexander Mohr 和 Ilya Kulakov 在 bpo-29302 中貢獻。)

cProfile

cProfile 命令列現在接受 -m module_name 作為指令碼路徑的替代方法。(由 Sanyam Khurana 在bpo-21862中貢獻。)

crypt

crypt 模組現在支援 Blowfish 雜湊方法。(由 Serhiy Storchaka 在 bpo-31664 中貢獻。)

mksalt() 函式現在允許指定雜湊的輪數。(由 Serhiy Storchaka 在 bpo-31702 中貢獻。)

datetime

新的 datetime.fromisoformat() 方法從 datetime.isoformat() 輸出的格式之一的字串構造一個 datetime 物件。(由 Paul Ganssle 在 bpo-15873 中貢獻。)

tzinfo 類現在支援子分鐘偏移。(由 Alexander Belopolsky 在bpo-5288中貢獻。)

dbm

dbm.dumb 現在支援讀取只讀檔案,並且在未更改索引檔案時不寫入索引檔案。

decimal

decimal 模組現在使用 上下文變數 來儲存十進位制上下文。(由 Yury Selivanov 在 bpo-32630 中貢獻。)

dis

dis() 函式現在能夠反彙編巢狀的程式碼物件(推導式、生成器表示式和巢狀函式的程式碼,以及用於構建巢狀類的程式碼)。反彙編遞迴的最大深度由新的 *depth* 引數控制。(由 Serhiy Storchaka 在 bpo-11822 中貢獻。)

distutils

README.rst 現在包含在 distutils 標準 README 列表中,因此包含在原始碼發行版中。(由 Ryan Gonzalez 在 bpo-11913 中貢獻。)

enum

Enum 學習了新的 _ignore_ 類屬性,允許列出不應成為列舉成員的屬性的名稱。(由 Ethan Furman 在 bpo-31801 中貢獻。)

在 Python 3.8 中,嘗試檢查 Enum 類中的非列舉物件會引發 TypeError(例如 1 in Color);類似地,嘗試檢查 Flag 成員中的非 Flag 物件會引發 TypeError(例如 1 in Perm.RW);目前,這兩個操作都返回 False,並且已被棄用。(由 Ethan Furman 在 bpo-33217 中貢獻。)

functools

functools.singledispatch() 現在支援使用型別註解註冊實現。(由 Łukasz Langa 在bpo-32227中貢獻。)

gc

新的 gc.freeze() 函式允許凍結垃圾收集器跟蹤的所有物件,並將它們排除在未來的集合之外。這可以在 POSIX fork() 呼叫之前使用,以使 GC 對寫入時複製友好或加速收集。新的 gc.unfreeze() 函式會反轉此操作。此外,gc.get_freeze_count() 可用於獲取凍結物件的數量。(由 Li Zekun 在bpo-31558 中貢獻。)

hmac

現在,hmac 模組有了一個最佳化的單次 digest() 函式,它的速度比 HMAC() 快三倍。(由 Christian Heimes 在 bpo-32433 中貢獻。)

http.client

HTTPConnectionHTTPSConnection 現在支援新的 blocksize 引數,以提高上傳吞吐量。(由 Nir Soffer 在 bpo-31945 中貢獻。)

http.server

SimpleHTTPRequestHandler 現在支援 HTTP If-Modified-Since 標頭。如果目標檔案在標頭中指定的時間之後未被修改,伺服器將返回 304 響應狀態。(由 Pierre Quentel 在 bpo-29654 中貢獻。)

SimpleHTTPRequestHandler 接受新的 directory 引數,以及新的 --directory 命令列引數。使用此引數,伺服器將服務於指定的目錄,預設情況下它使用當前工作目錄。(由 Stéphane Wirtel 和 Julien Palard 在 bpo-28707 中貢獻。)

新的 ThreadingHTTPServer 類使用執行緒透過 ThreadingMixin 處理請求。當使用 -m 執行 http.server 時使用它。(由 Julien Palard 在 bpo-31639 中貢獻。)

idlelib 和 IDLE

自動完成的多個修復。(由 Louie Lu 在 bpo-15786 中貢獻。)

模組瀏覽器(在檔案選單上,以前稱為類瀏覽器)現在除了頂層函式和類之外,還顯示巢狀的函式和類。(由 Guilherme Polo,Cheryl Sabella 和 Terry Jan Reedy 在 bpo-1612262 中貢獻。)

“設定”對話方塊(“選項”,“配置 IDLE”)已部分重寫,以改進外觀和功能。(由 Cheryl Sabella 和 Terry Jan Reedy 在多個問題中貢獻。)

字型示例現在包含非拉丁字元的選擇,以便使用者可以更好地瞭解選擇特定字型的影響。(由 Terry Jan Reedy 在 bpo-13802 中貢獻。)可以編輯示例以包含其他字元。(由 Serhiy Storchaka 在 bpo-31860 中貢獻。)

以前作為擴充套件實現的 IDLE 功能已重新實現為正常功能。它們的設定已從“擴充套件”選項卡移動到其他對話方塊選項卡。(由 Charles Wohlganger 和 Terry Jan Reedy 在 bpo-27099 中貢獻。)

修訂編輯器程式碼上下文選項。框顯示最多 maxlines 的所有上下文行。單擊上下文行會將編輯器跳轉到該行。自定義主題的上下文顏色已新增到“設定”對話方塊的“高亮顯示”選項卡。(由 Cheryl Sabella 和 Terry Jan Reedy 在 bpo-33642bpo-33768bpo-33679 中貢獻。)

在 Windows 上,新的 API 呼叫會告訴 Windows tk 為 DPI 縮放。在 Windows 8.1+ 或 10 上,Python 二進位制檔案的 DPI 相容性屬性保持不變,並且顯示器解析度大於 96 DPI,這應該使文字和線條更清晰。否則應該沒有效果。(由 Terry Jan Reedy 在 bpo-33656 中貢獻。)

3.7.1 中的新功能

超過 N 行(預設為 50 行)的輸出被壓縮成一個按鈕。可以在“設定”對話方塊的“常規”頁面的“PyShell”部分中更改 N。可以透過右鍵單擊輸出來壓縮更少但可能更長的行。可以透過雙擊按鈕將壓縮的輸出就地展開,或者透過右鍵單擊按鈕將其展開到剪貼簿或單獨的視窗中。(由 Tal Einat 在 bpo-1529353 中貢獻。)

以上更改已向後移植到 3.6 維護版本。

3.7.4 中的新功能

將“執行自定義”新增到“執行”選單,以使用自定義設定執行模組。輸入的任何命令列引數都將新增到 sys.argv。它們會在下一次自定義執行時重新出現在框中。還可以禁止正常的 Shell 主模組重新啟動。(由 Cheryl Sabella,Terry Jan Reedy 和其他人在 bpo-5680bpo-37627 中貢獻。)

3.7.5 中的新功能

為 IDLE 編輯器視窗新增可選的行號。除非在配置對話方塊的“常規”選項卡中另行設定,否則開啟的視窗不顯示行號。現有視窗的行號在“選項”選單中顯示和隱藏。(由 Tal Einat 和 Saimadhav Heblikar 在 bpo-17535 中貢獻。)

importlib

引入了 importlib.abc.ResourceReader ABC,以支援從包中載入資源。另請參見 importlib.resources。(由 Barry Warsaw,Brett Cannon 在 bpo-32248 中貢獻。)

如果模組缺少 spec,importlib.reload() 現在會引發 ModuleNotFoundError。(由 Garvit Khatri 在 bpo-29851 中貢獻。)

如果指定的父模組不是包(即缺少 __path__ 屬性),importlib.find_spec() 現在會引發 ModuleNotFoundError,而不是 AttributeError。(由 Milan Oberkirch 在 bpo-30436 中貢獻。)

新的 importlib.source_hash() 可用於計算傳遞的源的雜湊值。一個 基於雜湊的 .pyc 檔案 嵌入了此函式返回的值。

io

新的 TextIOWrapper.reconfigure() 方法可用於使用新設定重新配置文字流。(由 Antoine Pitrou 在 bpo-30526 和 INADA Naoki 在 bpo-15216 中貢獻。)

ipaddress

新的 subnet_of()supernet_of() 方法 ipaddress.IPv6Networkipaddress.IPv4Network 可用於網路包含測試。(由 Michel Albert 和 Cheryl Sabella 在 bpo-20825 中貢獻。)

itertools

itertools.islice() 現在接受 類整數物件 作為 start、stop 和 slice 引數。(由 Will Roberts 在 bpo-30537 中貢獻。)

locale

locale.format_string() 的新 monetary 引數可用於使轉換使用貨幣千位分隔符和分組字串。(由 Garvit 在 bpo-10379 中貢獻。)

現在,在 Android 上或在強制 UTF-8 模式下,locale.getpreferredencoding() 函式總是返回 'UTF-8'

日誌記錄

現在可以 pickle Logger 例項。(由 Vinay Sajip 在 bpo-30520 中貢獻。)

新的 StreamHandler.setStream() 方法可用於在處理程式建立後替換日誌記錄器流。(由 Vinay Sajip 在 bpo-30522 中貢獻。)

現在可以在傳遞給 logging.config.fileConfig() 的配置中,為處理程式建構函式指定關鍵字引數。(由 Preston Landers 在 bpo-31080 中貢獻。)

數學

新的 math.remainder() 函式實現了 IEEE 754 風格的餘數運算。(由 Mark Dickinson 在 bpo-29962 中貢獻。)

mimetypes

.bmp 的 MIME 型別已從 'image/x-ms-bmp' 更改為 'image/bmp'。(由 Nitish Chandra 在 bpo-22589 中貢獻。)

msilib

新的 Database.Close() 方法可用於關閉 MSI 資料庫。(由 Berker Peksag 在 bpo-20486 中貢獻。)

多程序

新的 Process.close() 方法顯式地關閉程序物件並釋放與之關聯的所有資源。如果底層程序仍在執行,則會引發 ValueError。(由 Antoine Pitrou 在 bpo-30596 中貢獻。)

新的 Process.kill() 方法可用於使用 Unix 上的 SIGKILL 訊號終止程序。(由 Vitor Pereira 在 bpo-30794 中貢獻。)

Process 建立的非守護執行緒現在在程序退出時被加入。(由 Antoine Pitrou 在 bpo-18966 中貢獻。)

os

現在,os.fwalk() 接受 path 引數作為 bytes。(由 Serhiy Storchaka 在 bpo-28682 中貢獻。)

os.scandir() 獲得了對檔案描述符 的支援。(由 Serhiy Storchaka 在 bpo-25996 中貢獻。)

新的 register_at_fork() 函式允許註冊在程序 fork 時執行的 Python 回撥。(由 Antoine Pitrou 在 bpo-16500 中貢獻。)

添加了 os.preadv() (合併了 os.readv()os.pread() 的功能) 和 os.pwritev() 函式 (合併了 os.writev()os.pwrite() 的功能)。(由 Pablo Galindo 在 bpo-31368 中貢獻。)

os.makedirs() 的 mode 引數不再影響新建立的中間級別目錄的檔案許可權位。(由 Serhiy Storchaka 在 bpo-19930 中貢獻。)

現在,os.dup2() 返回新的檔案描述符。以前,總是返回 None。(由 Benjamin Peterson 在 bpo-32441 中貢獻。)

現在,由 os.stat() 返回的結構在 Solaris 及其衍生版本上包含 st_fstype 屬性。(由 Jesús Cea Avión 在 bpo-32659 中貢獻。)

pathlib

新的 Path.is_mount() 方法現在在 POSIX 系統上可用,可用於確定路徑是否為掛載點。(由 Cooper Ry Lees 在 bpo-30897 中貢獻。)

pdb

現在,pdb.set_trace() 接受可選的僅限關鍵字的 header 引數。如果給定,它將在除錯開始之前列印到控制檯。(由 Barry Warsaw 在 bpo-31389 中貢獻。)

pdb 命令列現在接受 -m module_name 作為指令碼檔案的替代方法。(由 Mario Corchero 在 bpo-32206 中貢獻。)

py_compile

py_compile.compile() – 以及擴充套件的 compileall – 現在透過無條件地為基於雜湊的驗證建立 .pyc 檔案來遵循 SOURCE_DATE_EPOCH 環境變數。這允許在急切建立 .pyc 檔案時保證其可重現構建。(由 Bernhard M. Wiedemann 在 bpo-29708 中貢獻。)

pydoc

現在,pydoc 伺服器可以繫結到由新的 -n 命令列引數指定的任意主機名。(由 Feanil Patel 在 bpo-31128 中貢獻。)

queue

新的 SimpleQueue 類是一個無界的 FIFO 佇列。(由 Antoine Pitrou 在 bpo-14976 中貢獻。)

re

標誌 re.ASCIIre.LOCALEre.UNICODE 可以在組的範圍內設定。(由 Serhiy Storchaka 在 bpo-31690 中貢獻。)

現在,re.split() 支援拆分像 r'\b''^$'(?=-) 這樣與空字串匹配的模式。(由 Serhiy Storchaka 在 bpo-25054 中貢獻。)

使用 re.LOCALE 標誌編譯的正則表示式不再依賴於編譯時的區域設定。區域設定僅在編譯後的正則表示式使用時應用。(由 Serhiy Storchaka 在 bpo-30215 中貢獻。)

如果正則表示式包含將來語義會發生更改的字元集結構,例如巢狀集合和集合運算,則現在會發出 FutureWarning。(由 Serhiy Storchaka 在 bpo-30349 中貢獻。)

編譯後的正則表示式和匹配物件現在可以使用 copy.copy()copy.deepcopy() 進行復制。(由 Serhiy Storchaka 在 bpo-10076 中貢獻。)

signal

signal.set_wakeup_fd() 函式新增的 *warn_on_full_buffer* 引數,使得可以指定當喚醒緩衝區溢位時,Python 是否在 stderr 上列印警告。(由 Nathaniel J. Smith 在 bpo-30050 中貢獻。)

socket

新的 socket.getblocking() 方法,如果套接字處於阻塞模式則返回 True,否則返回 False。(由 Yury Selivanov 在 bpo-32373 中貢獻。)

新的 socket.close() 函式關閉傳遞的套接字檔案描述符。為了在不同平臺之間獲得更好的相容性,應該使用此函式而不是 os.close()。(由 Christian Heimes 在 bpo-32454 中貢獻。)

socket 模組現在公開了 socket.TCP_CONGESTION (Linux 2.6.13), socket.TCP_USER_TIMEOUT (Linux 2.6.37), 和 socket.TCP_NOTSENT_LOWAT (Linux 3.12) 常量。(由 Omar Sandoval 在 bpo-26273 中貢獻,以及 Nathaniel J. Smith 在 bpo-29728 中貢獻。)

已新增對 socket.AF_VSOCK 套接字的支援,以允許虛擬機器及其主機之間進行通訊。(由 Cathy Avery 在 bpo-27584 中貢獻。)

套接字現在預設從檔案描述符自動檢測系列、型別和協議。(由 Christian Heimes 在 bpo-28134 中貢獻。)

socketserver

socketserver.ThreadingMixIn.server_close() 現在等待所有非守護執行緒完成。socketserver.ForkingMixIn.server_close() 現在等待所有子程序完成。

socketserver.ForkingMixInsocketserver.ThreadingMixIn 類添加了一個新的 socketserver.ForkingMixIn.block_on_close 類屬性。將該類屬性設定為 False 可獲得 3.7 之前的行為。

sqlite3

當底層 SQLite 庫的版本為 3.6.11 或更高時,sqlite3.Connection 現在公開 backup() 方法。(由 Lele Gaifax 在 bpo-27645 中貢獻。)

sqlite3.connect() 的 *database* 引數現在接受任何 路徑類物件,而不僅僅是字串。(由 Anders Lorentsen 在 bpo-31843 中貢獻。)

ssl

ssl 模組現在使用 OpenSSL 的內建 API 而不是 match_hostname() 來檢查主機名或 IP 地址。值在 TLS 握手期間進行驗證。任何證書驗證錯誤,包括主機名檢查失敗,現在都會引發 SSLCertVerificationError 並中止握手,並帶有正確的 TLS 警報訊息。新的異常包含附加資訊。可以使用 SSLContext.hostname_checks_common_name 自定義主機名驗證。(由 Christian Heimes 在 bpo-31399 中貢獻。)

注意

改進的主機名檢查需要與 OpenSSL 1.0.2 或 1.1 相容的 *libssl* 實現。因此,不再支援 OpenSSL 0.9.8 和 1.0.1(有關更多詳細資訊,請參閱 平臺支援移除)。ssl 模組主要與 LibreSSL 2.7.2 及更新版本相容。

ssl 模組不再在 SNI TLS 擴充套件中傳送 IP 地址。(由 Christian Heimes 在 bpo-32185 中貢獻。)

match_hostname() 不再支援部分萬用字元,例如 www*.example.org。(由 Mandeep Singh 在 bpo-23033 中貢獻,以及 Christian Heimes 在 bpo-31399 中貢獻。)

ssl 模組的預設密碼套件選擇現在使用黑名單方法,而不是硬編碼的白名單。Python 不再重新啟用已被 OpenSSL 安全更新阻止的密碼。預設密碼套件選擇可以在編譯時配置。(由 Christian Heimes 在 bpo-31429 中貢獻。)

現在支援驗證包含國際化域名 (IDN) 的伺服器證書。作為此更改的一部分,SSLSocket.server_hostname 屬性現在以 A 標籤形式 ("xn--pythn-mua.org") 儲存預期的主機名,而不是以 U 標籤形式 ("pythön.org")。(由 Nathaniel J. Smith 和 Christian Heimes 在 bpo-28414 中貢獻。)

ssl 模組初步和實驗性地支援 TLS 1.3 和 OpenSSL 1.1.1。在 Python 3.7.0 釋出時,OpenSSL 1.1.1 仍在開發中,TLS 1.3 尚未最終確定。TLS 1.3 握手和協議的行為與 TLS 1.2 及更早版本略有不同,請參閱 TLS 1.3。(由 Christian Heimes 在 bpo-32947, bpo-20995, bpo-29136, bpo-30622bpo-33618 中貢獻)

SSLSocketSSLObject 不再有公共建構函式。直接例項化從來都不是一個文件化和支援的功能。例項必須使用 SSLContext 方法 wrap_socket()wrap_bio() 建立。(由 Christian Heimes 在 bpo-32951 中貢獻)

OpenSSL 1.1 的 API 提供了設定最小和最大 TLS 協議版本的功能,可透過 SSLContext.minimum_versionSSLContext.maximum_version 訪問。支援的協議由幾個新的標誌指示,例如 HAS_TLSv1_1。(由 Christian Heimes 在 bpo-32609 中貢獻。)

添加了 ssl.SSLContext.post_handshake_auth 來啟用,以及 ssl.SSLSocket.verify_client_post_handshake() 來啟動 TLS 1.3 後握手身份驗證。(由 Christian Heimes 在 gh-78851 中貢獻。)

字串

string.Template 現在允許你分別修改帶花括號佔位符和不帶花括號佔位符的正則表示式模式。(由 Barry Warsaw 在 bpo-1198569 中貢獻。)

subprocess

subprocess.run() 函式接受新的 *capture_output* 關鍵字引數。當為 true 時,將捕獲 stdout 和 stderr。這等效於將 subprocess.PIPE 作為 *stdout* 和 *stderr* 引數傳遞。(由 Bo Bayles 在 bpo-32102 中貢獻。)

subprocess.run 函式和 subprocess.Popen 建構函式現在接受 *text* 關鍵字引數作為 *universal_newlines* 的別名。(由 Andrew Clegg 在 bpo-31756 中貢獻。)

在 Windows 上,當重定向標準控制代碼時,*close_fds* 的預設值從 False 更改為 True。現在可以在重定向標準控制代碼時將 *close_fds* 設定為 true。請參閱 subprocess.Popen。這意味著 *close_fds* 現在在所有支援的平臺上預設為 True。(由 Segev Finer 在 bpo-19764 中貢獻。)

subprocess 模組現在在 subprocess.call()subprocess.run() 或在 Popen 上下文管理器中處理 KeyboardInterrupt 時更加優雅。現在,它會等待子程序退出一小段時間,然後再繼續處理 KeyboardInterrupt 異常。(由 Gregory P. Smith 在 bpo-25942 中貢獻。)

sys

新的 sys.breakpointhook() 鉤子函式由內建的 breakpoint() 呼叫。(由 Barry Warsaw 在 bpo-31353 中貢獻。)

在 Android 上,新的 sys.getandroidapilevel() 返回構建時的 Android API 版本。(由 Victor Stinner 在 bpo-28740 中貢獻。)

新的 sys.get_coroutine_origin_tracking_depth() 函式返回當前協程源跟蹤深度,該深度由新的 sys.set_coroutine_origin_tracking_depth() 設定。asyncio 已轉換為使用此新 API,而不是已棄用的 sys.set_coroutine_wrapper()。(由 Nathaniel J. Smith 在 bpo-32591 中貢獻。)

time

PEP 564time 模組添加了六個具有納秒解析度的新函式

添加了新的時鐘識別符號

新的 time.thread_time()time.thread_time_ns() 函式可用於獲取每個執行緒的 CPU 時間測量值。(由 Antoine Pitrou 在 bpo-32025 中貢獻。)

新的 time.pthread_getcpuclockid() 函式返回執行緒特定的 CPU 時間時鐘的時鐘 ID。

tkinter

現在可以使用新的 tkinter.ttk.Spinbox 類。(由 Alan Moore 在 bpo-32585 中貢獻。)

tracemalloc

tracemalloc.Traceback 的行為更像常規的回溯,按從最舊到最近的順序對幀進行排序。Traceback.format() 現在接受負數 *limit*,將結果截斷為 abs(limit) 最舊的幀。要獲得舊的行為,請使用 Traceback.format() 的新 *most_recent_first* 引數。(由 Jesse Bakker 在 bpo-32121 中貢獻。)

types

現在可以使用新的 WrapperDescriptorTypeMethodWrapperTypeMethodDescriptorTypeClassMethodDescriptorType 類。(由 Manuel Krebber 和 Guido van Rossum 在 bpo-29377 中貢獻,以及 Serhiy Storchaka 在 bpo-32265 中貢獻。)

新的 types.resolve_bases() 函式按照 PEP 560 的規定動態解析 MRO 條目。(由 Ivan Levkivskyi 在 bpo-32717 中貢獻。)

unicodedata

內部 unicodedata 資料庫已升級為使用 Unicode 11。(由 Benjamin Peterson 貢獻。)

unittest

新的 -k 命令列選項允許按名稱子字串或類似 Unix shell 的模式過濾測試。例如,python -m unittest -k foo 執行 foo_tests.SomeTest.test_somethingbar_tests.SomeTest.test_foo,但不執行 bar_tests.FooTest.test_something。(由 Jonas Haag 在 bpo-32071 中貢獻。)

unittest.mock

現在,當 sentinel 屬性被 複製封存 時,它們會保留其身份。(由 Serhiy Storchaka 在 bpo-20804 中貢獻。)

新的 seal() 函式允許密封 Mock 例項,這將禁止進一步建立屬性模擬。密封會遞迴地應用於所有本身是模擬的屬性。(由 Mario Corchero 在 bpo-30541 中貢獻。)

urllib.parse

urllib.parse.quote() 已從 RFC 2396 更新為 RFC 3986,將 ~ 新增到預設情況下永遠不會被引用的字元集中。(由 Christian Theune 和 Ratnadeep Debnath 在 bpo-16285 中貢獻。)

uu

uu.encode() 函式現在接受一個可選的 backtick 關鍵字引數。當它為 true 時,零由 '`' 表示而不是空格。(由 Xiang Zhang 在 bpo-30103 中貢獻。)

uuid

新的 UUID.is_safe 屬性從平臺傳遞有關生成的 UUID 是否使用多程序安全方法生成的資訊。(由 Barry Warsaw 在 bpo-22807 中貢獻。)

uuid.getnode() 現在優先使用全域性管理的 MAC 地址而不是本地管理的 MAC 地址。這為從 uuid.uuid1() 返回的 UUID 的全域性唯一性提供了更好的保證。如果只有本地管理的 MAC 地址可用,則返回找到的第一個。(由 Barry Warsaw 在 bpo-32107 中貢獻。)

warnings

預設警告過濾器的初始化已更改如下:

  • 透過命令列選項啟用的警告(包括 -b 和新的 CPython 特有的 -X dev 選項)始終透過 sys.warnoptions 屬性傳遞給警告機制。

  • 透過命令列或環境啟用的警告過濾器現在具有以下優先順序順序:

    • 用於 -b(或 -bb)的 BytesWarning 過濾器

    • 使用 -W 選項指定的任何過濾器

    • 使用 PYTHONWARNINGS 環境變數指定的任何過濾器

    • 任何其他 CPython 特定的過濾器(例如,為新的 -X dev 模式新增的 default 過濾器)

    • 由警告機制直接定義的任何隱式過濾器

  • CPython 除錯版本 中,預設情況下會顯示所有警告(隱式過濾器列表為空)

(由 Nick Coghlan 和 Victor Stinner 在 bpo-20361bpo-32043bpo-32230 中貢獻。)

棄用警告再次預設顯示在單檔案指令碼和互動式提示中。有關詳細資訊,請參閱 PEP 565: 在 __main__ 中顯示 DeprecationWarning。(由 Nick Coghlan 在 bpo-31975 中貢獻。)

xml

為了緩解 DTD 和外部實體檢索問題,xml.dom.minidomxml.sax 模組預設情況下不再處理外部實體。(由 Christian Heimes 在 gh-61441 中貢獻。)

xml.etree

find() 方法中的 ElementPath 謂詞現在可以將當前節點的文字與 [. = "text"] 進行比較,而不僅僅是子節點的文字。謂詞還允許新增空格以提高可讀性。(由 Stefan Behnel 在 bpo-31648 中貢獻。)

xmlrpc.server

SimpleXMLRPCDispatcher.register_function 現在可以用作裝飾器。(由 Xiang Zhang 在 bpo-7769 中貢獻。)

zipapp

函式 create_archive() 現在接受一個可選的 filter 引數,允許使用者選擇應包含在存檔中的檔案。(由 Irmen de Jong 在 bpo-31072 中貢獻。)

函式 create_archive() 現在接受一個可選的 compressed 引數來生成壓縮的存檔。還添加了一個命令列選項 --compress 來支援壓縮。(由 Zhiming Wang 在 bpo-31638 中貢獻。)

zipfile

ZipFile 現在接受新的 compresslevel 引數來控制壓縮級別。(由 Bo Bayles 在 bpo-21417 中貢獻。)

ZipFile 建立的存檔中的子目錄現在按字母順序儲存。(由 Bernhard M. Wiedemann 在 bpo-30693 中貢獻。)

C API 更改

已實現用於執行緒區域性儲存的新 API。有關概述,請參閱 PEP 539:用於執行緒區域性儲存的新 C API,有關完整參考,請參閱 執行緒特定儲存 (TSS) API。(由 Masayuki Yamamoto 在 bpo-25658 中貢獻。)

新的 上下文變數 功能公開了許多 新的 C API

新的 PyImport_GetModule() 函式返回先前匯入的具有給定名稱的模組。(由 Eric Snow 在 bpo-28411 中貢獻。)

新的 Py_RETURN_RICHCOMPARE 宏簡化了編寫富比較函式的過程。(由 Petr Victorin 在 bpo-23699 中貢獻。)

新的 Py_UNREACHABLE 宏可以用來標記不可達的程式碼路徑。(由 Barry Warsaw 在 bpo-31338 中貢獻。)

tracemalloc 現在透過新的 PyTraceMalloc_Track()PyTraceMalloc_Untrack() 函式公開 C API。(由 Victor Stinner 在 bpo-30054 中貢獻。)

新的 import__find__load__start()import__find__load__done() 靜態標記可用於跟蹤模組匯入。(由 Christian Heimes 在 bpo-31574 中貢獻。)

結構體 PyMemberDef, PyGetSetDef, PyStructSequence_Field, PyStructSequence_Desc, 和 wrapperbase 的欄位 namedoc 現在是 const char * 型別,而不是 char * 型別。(由 Serhiy Storchaka 在 bpo-28761 中貢獻。)

PyUnicode_AsUTF8AndSize()PyUnicode_AsUTF8() 的結果現在是 const char * 型別,而不是 char * 型別。(由 Serhiy Storchaka 在 bpo-28769 中貢獻。)

PyMapping_Keys(), PyMapping_Values()PyMapping_Items() 的結果現在總是列表,而不是列表或元組。(由 Oren Milman 在 bpo-28280 中貢獻。)

添加了函式 PySlice_Unpack()PySlice_AdjustIndices()。(由 Serhiy Storchaka 在 bpo-27867 中貢獻。)

PyOS_AfterFork() 已被棄用,取而代之的是新函式 PyOS_BeforeFork(), PyOS_AfterFork_Parent()PyOS_AfterFork_Child()。(由 Antoine Pitrou 在 bpo-16500 中貢獻。)

作為公共 API 一部分的 PyExc_RecursionErrorInst 單例已被移除,因為它的成員從未被清除,可能會在直譯器的最終化過程中導致段錯誤。由 Xavier de Gaye 在 bpo-22898bpo-30697 中貢獻。

添加了對時區的 C API 支援,包括時區建構函式 PyTimeZone_FromOffset()PyTimeZone_FromOffsetAndName(),以及透過 PyDateTime_TimeZone_UTC 訪問 UTC 單例。由 Paul Ganssle 在 bpo-10381 中貢獻。

PyThread_start_new_thread()PyThread_get_thread_ident() 的結果型別,以及 PyThreadState_SetAsyncExc()id 引數的型別從 long 更改為 unsigned long。(由 Serhiy Storchaka 在 bpo-6532 中貢獻。)

如果第二個引數是 NULL 並且 wchar_t* 字串包含空字元,PyUnicode_AsWideCharString() 現在會引發 ValueError。(由 Serhiy Storchaka 在 bpo-30708 中貢獻。)

啟動序列和動態記憶體分配器管理方面的更改意味著,長期以來記錄的要求在呼叫大多數 C API 函式之前呼叫 Py_Initialize() 現在更加依賴,不遵守可能會導致嵌入式應用程式出現段錯誤。有關更多詳細資訊,請參閱本文件中的 移植到 Python 3.7 部分和 C API 文件中的 在 Python 初始化之前 部分。

新的 PyInterpreterState_GetID() 返回給定直譯器的唯一 ID。(由 Eric Snow 在 bpo-29102 中貢獻。)

當啟用 UTF-8 模式 時,Py_DecodeLocale(), Py_EncodeLocale() 現在使用 UTF-8 編碼。(由 Victor Stinner 在 bpo-29240 中貢獻。)

PyUnicode_DecodeLocaleAndSize()PyUnicode_EncodeLocale() 現在為 surrogateescape 錯誤處理程式使用當前區域設定編碼。(由 Victor Stinner 在 bpo-29240 中貢獻。)

PyUnicode_FindChar()startend 引數現在被調整為像字串切片一樣工作。(由 Xiang Zhang 在 bpo-28822 中貢獻。)

構建更改

已刪除對構建 --without-threads 的支援。 threading 模組現在始終可用。(由 Antoine Pitrou 在 bpo-31370 中貢獻。)

在非 OSX UNIX 平臺上構建 _ctypes 模組時,不再捆綁 libffi 的完整副本。 在此類平臺上構建 _ctypes 時,現在需要安裝 libffi 的副本。(由 Zachary Ware 在 bpo-27979 中貢獻。)

Windows 構建過程不再依賴 Subversion 來拉取外部源,而是使用 Python 指令碼從 GitHub 下載 zip 檔案。 如果在系統上找不到 Python 3.6(透過 py -3.6),則使用 NuGet 下載 32 位 Python 的副本用於此目的。(由 Zachary Ware 在 bpo-30450 中貢獻。)

ssl 模組需要 OpenSSL 1.0.2 或 1.1 相容的 libssl。OpenSSL 1.0.1 已於 2016-12-31 達到生命週期結束,不再受支援。LibreSSL 也暫時不受支援。LibreSSL 版本直至 2.6.4 都缺少所需的 OpenSSL 1.0.2 API。

效能最佳化

透過將更多程式碼移植到使用 METH_FASTCALL 約定,顯著減少了呼叫 C 中實現的各種標準庫類的許多方法的開銷。(由 Victor Stinner 在 bpo-29300, bpo-29507, bpo-29452, 和 bpo-29286 中貢獻。)

各種最佳化措施使 Linux 上的 Python 啟動時間減少了 10%,macOS 上減少了高達 30%。(由 Victor Stinner, INADA Naoki 在 bpo-29585 中,以及 Ivan Levkivskyi 在 bpo-31333 中貢獻。)

由於位元組碼的更改避免了建立繫結方法例項,方法呼叫現在快了 20%。(由 Yury Selivanov 和 INADA Naoki 在 bpo-26110 中貢獻。)

asyncio 模組為常用函式進行了許多顯著的最佳化。

由於 PEP 560 的工作typing 的匯入時間減少了 7 倍,並且許多型別操作現在更快了。(由 Ivan Levkivskyi 在 bpo-32226 中貢獻。)

sorted()list.sort() 針對常見情況進行了最佳化,速度提高了 40-75%。(由 Elliot Gorokhovsky 在 bpo-28685 中貢獻。)

dict.copy() 現在快了 5.5 倍。(由 Yury Selivanov 在 bpo-31179 中貢獻。)

當找不到 *name* 且 *obj* 不覆蓋 object.__getattr__()object.__getattribute__() 時,hasattr()getattr() 現在快了大約 4 倍。(由 INADA Naoki 在 bpo-32544 中貢獻。)

在字串中搜索某些 Unicode 字元(如烏克蘭大寫字母“Є”)的速度比搜尋其他字元慢 25 倍。現在最壞情況下只慢 3 倍。(由 Serhiy Storchaka 在 bpo-24821 中貢獻。)

collections.namedtuple() 工廠已重新實現,使命名元組的建立速度提高了 4 到 6 倍。(由 Jelle Zijlstra 貢獻,並由 INADA Naoki、Serhiy Storchaka 和 Raymond Hettinger 進一步改進,見 bpo-28638。)

date.fromordinal()date.fromtimestamp() 在常見情況下現在快了 30%。(由 Paul Ganssle 在 bpo-32403 中貢獻。)

由於使用了 os.scandir()os.fwalk() 函式現在快了 2 倍。(由 Serhiy Storchaka 在 bpo-25996 中貢獻。)

由於使用了 os.scandir() 函式,shutil.rmtree() 函式的速度提高了 20-40%。(由 Serhiy Storchaka 在 bpo-28564 中貢獻。)

優化了 正則表示式 的不區分大小寫的匹配和搜尋。現在搜尋某些模式的速度可以快 20 倍。(由 Serhiy Storchaka 在 bpo-30285 中貢獻。)

如果 flags 引數是 RegexFlagre.compile() 現在會將它轉換為 int 物件。現在它的速度與 Python 3.5 一樣快,並且根據模式的不同,比 Python 3.6 快約 10%。(由 INADA Naoki 在 bpo-31671 中貢獻。)

在重負載下,selectors.EpollSelectorselectors.PollSelectorselectors.DevpollSelector 類的 modify() 方法可能會快 10% 左右。(由 Giampaolo Rodola’ 在 bpo-30014 中貢獻。)

常量摺疊已從窺孔最佳化器移至新的 AST 最佳化器,該最佳化器能夠更一致地執行最佳化。(由 Eugene Toder 和 INADA Naoki 在 bpo-29469bpo-11549 中貢獻。)

abc 中的大多數函式和方法都已用 C 重寫。這使得建立抽象基類以及在其上呼叫 isinstance()issubclass() 的速度提高了 1.5 倍。這也使 Python 啟動時間減少了高達 10%。(由 Ivan Levkivskyi 和 INADA Naoki 在 bpo-31333 中貢獻。)

透過在不構造子類時使用快速路徑建構函式,顯著提高了 datetime.datedatetime.datetime 的備用建構函式的速度。(由 Paul Ganssle 在 bpo-32403 中貢獻。)

在某些情況下,array.array 例項的比較速度得到了顯著提高。當比較儲存相同整數型別值的陣列時,速度現在快了 10 到 70 倍。(由 Adrian Wielgosik 在 bpo-24700 中貢獻。)

math.erf()math.erfc() 函式現在在大多數平臺上使用(更快的)C 庫實現。(由 Serhiy Storchaka 在 bpo-26121 中貢獻。)

其他 CPython 實現更改

  • 跟蹤鉤子現在可以選擇不接收 line,而是透過設定幀上相應的新的 f_trace_linesf_trace_opcodes 屬性,從直譯器接收 opcode 事件。(由 Nick Coghlan 在 bpo-31344 中貢獻。)

  • 修復了名稱空間包模組屬性的一些一致性問題。名稱空間模組物件現在有一個 __file__ 屬性,其值設定為 None (之前未設定),並且它們的 __spec__.origin 也被設定為 None (之前是字串 "namespace")。請參閱 bpo-32305。此外,名稱空間模組物件的 __spec__.loader 被設定為與 __loader__ 相同的值(之前,前者被設定為 None)。請參閱 bpo-32303

  • locals() 字典現在按照變數定義的詞法順序顯示。之前,順序是未定義的。(由 Raymond Hettinger 在 bpo-32690 中貢獻。)

  • distutils upload 命令不再嘗試將 CR 行尾字元更改為 CRLF。這修復了 sdist 以等效於 CR 的位元組結尾時的損壞問題。(由 Bo Bayles 在 bpo-32304 中貢獻。)

已棄用的 Python 行為

yield 表示式(包括 yieldyield from 子句)現在在推導式和生成器表示式中已被棄用(最左側 for 子句中的可迭代表達式除外)。這確保了推導式總是立即返回適當型別的容器(而不是可能返回一個 生成器迭代器 物件),而生成器表示式不會嘗試將其隱式輸出與任何顯式 yield 表示式的輸出交錯。在 Python 3.7 中,此類表示式在編譯時會發出 DeprecationWarning,在 Python 3.8 中,這將是一個 SyntaxError。(由 Serhiy Storchaka 在 bpo-10544 中貢獻。)

object.__complex__() 返回 complex 的子類已被棄用,並且在未來的 Python 版本中將引發錯誤。這使得 __complex__()object.__int__()object.__float__() 一致。(由 Serhiy Storchaka 在 bpo-28894 中貢獻。)

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

aifc

aifc.openfp() 已被棄用,將在 Python 3.9 中刪除。請改用 aifc.open()。(由 Brian Curtin 在 bpo-31985 中貢獻。)

asyncio

直接 await-ing asyncio.Lock 和其他 asyncio 同步原語的例項的支援已被棄用。必須使用非同步上下文管理器才能獲取和釋放同步資源。(由 Andrew Svetlov 在 bpo-32253 中貢獻。)

asyncio.Task.current_task()asyncio.Task.all_tasks() 方法已被棄用。(由 Andrew Svetlov 在 bpo-32250 中貢獻。)

collections

在 Python 3.8 中,collections.abc 中的抽象基類將不再在常規 collections 模組中公開。這將有助於在具體類和抽象基類之間建立更清晰的區別。(由 Serhiy Storchaka 在 bpo-25988 中貢獻。)

dbm

dbm.dumb 現在支援讀取只讀檔案,並且在索引檔案未更改時不再寫入索引檔案。如果索引檔案丟失並在 'r''w' 模式下重新建立,則現在會發出棄用警告(這在未來的 Python 版本中將是一個錯誤)。(由 Serhiy Storchaka 在 bpo-28847 中貢獻。)

enum

在 Python 3.8 中,嘗試在 Enum 類中檢查非 Enum 物件將引發 TypeError(例如 1 in Color);類似地,嘗試在 Flag 成員中檢查非 Flag 物件將引發 TypeError(例如 1 in Perm.RW);目前,這兩個操作都返回 False。(由 Ethan Furman 在 bpo-33217 中貢獻。)

gettext

gettext 中使用非整數值選擇複數形式現在已被棄用。它從來沒有正確地工作過。(由 Serhiy Storchaka 在 bpo-28692 中貢獻。)

importlib

方法 MetaPathFinder.find_module()(由 MetaPathFinder.find_spec() 替換)和 PathEntryFinder.find_loader()(由 PathEntryFinder.find_spec() 替換)都在 Python 3.4 中被棄用,現在會發出 DeprecationWarning。(由 Matthias Bussonnier 在 bpo-29576 中貢獻。)

importlib.abc.ResourceLoader ABC 已被棄用,轉而支援 importlib.abc.ResourceReader

locale

locale.format() 已被棄用,請改用 locale.format_string()。(由 Garvit 在 bpo-10379 中貢獻。)

macpath

macpath 現在已被棄用,將在 Python 3.8 中刪除。(由 Chi Hsuan Yen 在 bpo-9850 中貢獻。)

threading

dummy_threading_dummy_thread 已被棄用。不再可能在停用執行緒的情況下構建 Python。請改用 threading。(由 Antoine Pitrou 在 bpo-31370 中貢獻。)

socket

socket.htons()socket.ntohs() 中,靜默截斷引數值已被棄用。在未來的 Python 版本中,如果傳遞的引數大於 16 位,將引發異常。(由 Oren Milman 在 bpo-28332 中貢獻。)

ssl

ssl.wrap_socket() 已被棄用。請改用 ssl.SSLContext.wrap_socket()。(由 Christian Heimes 在 bpo-28124 中貢獻。)

sunau

sunau.openfp() 已被棄用,將在 Python 3.9 中刪除。請改用 sunau.open()。(由 Brian Curtin 在 bpo-31985 中貢獻。)

sys

已棄用 sys.set_coroutine_wrapper()sys.get_coroutine_wrapper()

未公開的 sys.callstats() 函式已被棄用,並將在未來的 Python 版本中刪除。(由 Victor Stinner 在 bpo-28799 中貢獻。)

wave

wave.openfp() 已被棄用,並將在 Python 3.9 中刪除。請改用 wave.open()。(由 Brian Curtin 在 bpo-31985 中貢獻。)

C API 中已棄用的函式和型別

函式 PySlice_GetIndicesEx() 已被棄用,如果未設定 Py_LIMITED_API,或設定為 0x030504000x03060000 (不包含) 之間的值,或者為 0x03060100 或更高版本,則會用宏替換。(由 Serhiy Storchaka 在 bpo-27867 中貢獻。)

PyOS_AfterFork() 已被棄用。請改用 PyOS_BeforeFork()PyOS_AfterFork_Parent()PyOS_AfterFork_Child()。(由 Antoine Pitrou 在 bpo-16500 中貢獻。)

平臺支援移除

  • 不再正式支援 FreeBSD 9 及更早版本。

  • 為了完全支援 Unicode,包括在擴充套件模組中,現在期望 *nix 平臺至少提供 C.UTF-8(完整區域設定)、C.utf8(完整區域設定)或 UTF-8(僅 LC_CTYPE 區域設定)中的一個,作為基於舊的 ASCIIC 區域設定的替代方案。

  • 不再支援 OpenSSL 0.9.8 和 1.0.1,這意味著在仍然使用這些版本的較舊平臺上構建具有 SSL/TLS 支援的 CPython 3.7 需要自定義構建選項,這些選項鍊接到更新版本的 OpenSSL。

    值得注意的是,此問題會影響 Debian 8(又名“jessie”)和 Ubuntu 14.04(又名“Trusty”)LTS Linux 發行版,因為它們預設仍使用 OpenSSL 1.0.1。

    Debian 9(“stretch”)和 Ubuntu 16.04(“xenial”)以及其他 LTS Linux 發行版的最新版本(例如 RHEL/CentOS 7.5、SLES 12-SP3)使用 OpenSSL 1.0.2 或更高版本,並且在預設構建配置中仍然受支援。

    CPython 自己的 CI 配置檔案 提供了一個示例,說明如何在 CPython 的測試套件中使用 SSL 相容性測試基礎設施,以構建和連結到 OpenSSL 1.1.0 而不是過時的系統提供的 OpenSSL。

API 和功能移除

以下功能和 API 已從 Python 3.7 中刪除

  • os.stat_float_times() 函式已被刪除。它是在 Python 2.3 中引入的,用於與 Python 2.2 向後相容,並且自 Python 3.1 起已棄用。

  • re.sub() 的替換模板中,由 '\' 和 ASCII 字母組成的未知跳脫字元在 Python 3.5 中已棄用,現在將導致錯誤。

  • 刪除了 tarfile.TarFile.add() 中對 exclude 引數的支援。它在 Python 2.7 和 3.2 中已棄用。請改用 filter 引數。

  • ntpath.splitunc() 函式在 Python 3.1 中已棄用,現在已刪除。請改用 splitdrive()

  • collections.namedtuple() 不再支援 verbose 引數或顯示命名元組類生成的原始碼的 _source 屬性。這是旨在加快類建立速度的最佳化的一部分。(由 Jelle Zijlstra 貢獻,並由 INADA Naoki、Serhiy Storchaka 和 Raymond Hettinger 進一步改進,在 bpo-28638 中。)

  • 函式 bool()float()list()tuple() 不再接受關鍵字引數。int() 的第一個引數現在只能作為位置引數傳遞。

  • 刪除了 plistlib 模組中以前在 Python 2.4 中已棄用的類 PlistDict_InternalDict。函式 readPlist()readPlistFromBytes() 的結果中的 Dict 值現在是普通的 dict。您不能再使用屬性訪問來訪問這些字典的項。

  • asyncio.windows_utils.socketpair() 函式已被刪除。請改用 socket.socketpair() 函式,它自 Python 3.5 起在所有平臺上都可用。asyncio.windows_utils.socketpair 只是 Python 3.5 及更高版本中 socket.socketpair 的別名。

  • asyncio 不再將 selectors_overlapped 模組匯出為 asyncio.selectorsasyncio._overlapped。將 from asyncio import selectors 替換為 import selectors

  • 現在禁止直接例項化 ssl.SSLSocketssl.SSLObject 物件。這些建構函式從未被記錄、測試或設計為公共建構函式。使用者應該使用 ssl.wrap_socket()ssl.SSLContext。(由 Christian Heimes 在 bpo-32951 中貢獻。)

  • 已刪除未使用的 distutils install_misc 命令。(由 Eric N. Vander Weele 在 bpo-29218 中貢獻。)

模組移除

fpectl 模組已被刪除。它從未預設啟用,在 x86-64 上從未正確工作,並且它以導致 C 擴充套件意外中斷的方式更改了 Python ABI。(由 Nathaniel J. Smith 在 bpo-29137 中貢獻。)

僅限 Windows 的更改

python 啟動器 (py.exe) 可以接受 32 位和 64 位說明符,而無需同時指定次要版本。因此,py -3-32py -3-64 以及 py -3.7-32 都變為有效,並且現在接受 -m-64 和 -m.n-64 形式,以強制使用 64 位 python,即使本來會使用 32 位。如果指定的版本不可用,py.exe 將錯誤退出。(由 Steve Barnes 在 bpo-30291 中貢獻。)

可以使用 py -0 執行啟動器,以生成已安裝 Python 的列表,預設版本會用星號標記。執行 py -0p 將包含路徑。如果 py 執行時使用了無法匹配的版本指定符,它還會列印可用指定符的簡短形式列表。(由 Steve Barnes 在 bpo-30362 中貢獻。)

移植到 Python 3.7

本節列出了之前描述的更改和其他可能需要更改程式碼的錯誤修復。

Python 行為的更改

  • asyncawait 名稱現在是保留關鍵字。將這些名稱用作識別符號的程式碼現在會引發 SyntaxError。(由 Jelle Zijlstra 在 bpo-30406 中貢獻。)

  • PEP 479 在 Python 3.7 的所有程式碼中啟用,這意味著在協程和生成器中直接或間接引發的 StopIteration 異常會被轉換為 RuntimeError 異常。(由 Yury Selivanov 在 bpo-32670 中貢獻。)

  • object.__aiter__() 方法不能再宣告為非同步。(由 Yury Selivanov 在 bpo-31709 中貢獻。)

  • 由於疏忽,早期 Python 版本錯誤地接受了以下語法

    f(1 for x in [1],)
    
    class C(1 for x in [1]):
        pass
    

    Python 3.7 現在會正確引發 SyntaxError,因為生成器表示式必須始終直接位於一組括號內,並且兩側都不能有逗號,並且只有在呼叫時才能省略括號的重複。(由 Serhiy Storchaka 在 bpo-32012bpo-32023 中貢獻。)

  • 當使用 -m 開關時,初始工作目錄現在被新增到 sys.path 中,而不是一個空字串(它在每次匯入時動態表示當前工作目錄)。任何檢查空字串或以其他方式依賴先前行為的程式都需要進行相應的更新(例如,透過同時檢查 os.getcwd()os.path.dirname(__main__.__file__),具體取決於程式碼最初檢查空字串的原因)。

Python API 的更改

  • socketserver.ThreadingMixIn.server_close() 現在會等待所有非守護執行緒完成。將新的 socketserver.ThreadingMixIn.block_on_close 類屬性設定為 False 以獲得 3.7 之前的行為。(由 Victor Stinner 在 bpo-31233bpo-33540 中貢獻。)

  • socketserver.ForkingMixIn.server_close() 現在會等待所有子程序完成。將新的 socketserver.ForkingMixIn.block_on_close 類屬性設定為 False 以獲得 3.7 之前的行為。(由 Victor Stinner 在 bpo-31151bpo-33540 中貢獻。)

  • locale.localeconv() 函式現在在某些情況下會臨時將 LC_CTYPE 區域設定設定為 LC_NUMERIC 的值。(由 Victor Stinner 在 bpo-31900 中貢獻。)

  • 如果 path 是字串,pkgutil.walk_packages() 現在會引發 ValueError。之前會返回一個空列表。(由 Sanyam Khurana 在 bpo-24744 中貢獻。)

  • string.Formatter.format() 的格式字串引數現在是僅位置引數。在 Python 3.5 中,將其作為關鍵字引數傳遞已被棄用。(由 Serhiy Storchaka 在 bpo-29193 中貢獻。)

  • http.cookies.Morsel 的屬性 keyvaluecoded_value 現在是隻讀的。在 Python 3.5 中,賦值給它們已被棄用。使用 set() 方法來設定它們。(由 Serhiy Storchaka 在 bpo-29192 中貢獻。)

  • os.makedirs()mode 引數不再影響新建立的中間層目錄的檔案許可權位。要設定它們的檔案許可權位,可以在呼叫 makedirs() 之前設定 umask。(由 Serhiy Storchaka 在 bpo-19930 中貢獻。)

  • struct.Struct.format 型別現在是 str 而不是 bytes。(由 Victor Stinner 在 bpo-21071 中貢獻。)

  • cgi.parse_multipart() 現在接受 encodingerrors 引數,並返回與 FieldStorage 相同的結果:對於非檔案欄位,與鍵關聯的值是字串列表,而不是位元組。(由 Pierre Quentel 在 bpo-29979 中貢獻。)

  • 由於 socket 的內部更改,不支援在舊版本 Python 中使用 socket.share 建立的套接字上呼叫 socket.fromshare()

  • BaseExceptionrepr 已更改為不包括尾隨逗號。大多數異常都會受到此更改的影響。(由 Serhiy Storchaka 在 bpo-30399 中貢獻。)

  • datetime.timedeltarepr 已更改為在輸出中包含關鍵字引數。(由 Utkarsh Upadhyay 在 bpo-30302 中貢獻。)

  • 由於 shutil.rmtree() 現在使用 os.scandir() 函式實現,當列出目錄失敗時,使用者指定的處理程式 onerror 現在會使用第一個引數 os.scandir 而不是 os.listdir 呼叫。

  • 未來可能會新增對正則表示式中巢狀集合和集合運算的支援,如 Unicode 技術標準 #18 所述。 這將會改變語法。 為了方便未來的這種變更,目前在有歧義的情況下會引發 FutureWarning 警告。 這包括以字面量 '[' 開頭的集合,或包含字面字元序列 '--', '&&', '~~''||' 的集合。 要避免警告,請使用反斜槓轉義它們。(由 Serhiy Storchaka 在 bpo-30349 中貢獻。)

  • 使用可能匹配空字串的正則表示式分割字串的結果已更改。 例如,使用 r'\s*' 分割現在不僅會像以前一樣在空白處分割,還會在所有非空白字元之前以及字串末尾之前分割空字串。 可以透過將模式更改為 r'\s+' 來恢復以前的行為。 自 Python 3.5 起,對於此類模式會發出 FutureWarning 警告。

    對於同時匹配空字串和非空字串的模式,在其他情況下搜尋所有匹配項的結果也可能發生變化。 例如,在字串 'a\n\n' 中,模式 r'(?m)^\s*?$' 不僅會匹配位置 2 和 3 的空字串,還會匹配位置 2-3 的字串 '\n' 。 要僅匹配空行,應將模式重寫為 r'(?m)^[^\S\n]*$'

    re.sub() 現在會替換與前一個非空匹配項相鄰的空匹配項。 例如, re.sub('x*', '-', 'abxd') 現在返回 '-a-b--d-' 而不是 '-a-b-d-'('b' 和 'd' 之間的第一個減號替換 'x',第二個減號替換 'x' 和 'd' 之間的空字串)。

    (由 Serhiy Storchaka 在 bpo-25054bpo-32308 中貢獻。)

  • 更改 re.escape() 為僅轉義正則表示式特殊字元,而不是轉義除 ASCII 字母、數字和 '_' 以外的所有字元。(由 Serhiy Storchaka 在 bpo-29995 中貢獻。)

  • tracemalloc.Traceback 幀現在按從舊到新的順序排序,以便與 traceback 更加一致。(由 Jesse Bakker 在 bpo-32121 中貢獻。)

  • 在支援 socket.SOCK_NONBLOCKsocket.SOCK_CLOEXEC 位標誌的作業系統上,socket.type 不再應用它們。 因此,像 if sock.type == socket.SOCK_STREAM 這樣的檢查在所有平臺上都可以按預期工作。(由 Yury Selivanov 在 bpo-32331 中貢獻。)

  • 在 Windows 上,當重定向標準控制代碼時,subprocess.Popen 的 *close_fds* 引數的預設值從 False 更改為 True。 如果您之前依賴於在使用帶有標準 I/O 重定向的 subprocess.Popen 時繼承控制代碼,則必須傳遞 close_fds=False 以保留之前的行為,或使用 STARTUPINFO.lpAttributeList

  • importlib.machinery.PathFinder.invalidate_caches() – 這會隱式影響 importlib.invalidate_caches() – 現在會刪除 sys.path_importer_cache 中設定為 None 的條目。(由 Brett Cannon 在 bpo-33169 中貢獻。)

  • asyncio 中,loop.sock_recv()loop.sock_sendall()loop.sock_accept()loop.getaddrinfo()loop.getnameinfo() 已更改為適當的協程方法,以匹配其文件。 以前,這些方法返回 asyncio.Future 例項。(由 Yury Selivanov 在 bpo-32327 中貢獻。)

  • asyncio.Server.sockets 現在返回伺服器套接字的內部列表的副本,而不是直接返回它。(由 Yury Selivanov 在 bpo-32662 中貢獻。)

  • Struct.format 現在是 str 例項,而不是 bytes 例項。(由 Victor Stinner 在 bpo-21071 中貢獻。)

  • 現在可以透過將 required=True 傳遞給 ArgumentParser.add_subparsers() 來使 argparse 子解析器成為強制性的。(由 Anthony Sottile 在 bpo-26510 中貢獻。)

  • ast.literal_eval() 現在更加嚴格。 不再允許對任意數字進行加法和減法運算。(由 Serhiy Storchaka 在 bpo-31778 中貢獻。)

  • 當日期超出 0001-01-019999-12-31 範圍時,Calendar.itermonthdates 現在將一致地引發異常。 為了支援無法容忍此類異常的應用程式,可以使用新的 Calendar.itermonthdays3Calendar.itermonthdays4。 新方法返回元組,並且不受 datetime.date 支援的範圍的限制。(由 Alexander Belopolsky 在 bpo-28292 中貢獻。)

  • collections.ChainMap 現在保留基礎對映的順序。(由 Raymond Hettinger 在 bpo-32792 中貢獻。)

  • 現在,如果在直譯器關閉期間呼叫 concurrent.futures.ThreadPoolExecutorconcurrent.futures.ProcessPoolExecutorsubmit() 方法,則會引發 RuntimeError 異常。(由 Mark Nemec 在 bpo-33097 中貢獻。)

  • 現在,configparser.ConfigParser 建構函式使用 read_dict() 來處理預設值,使其行為與解析器的其餘部分保持一致。現在,預設字典中的非字串鍵和值會被隱式轉換為字串。(由 James Tocknell 在 bpo-23835 中貢獻。)

  • 刪除了幾個未公開的內部匯入。一個例子是 os.errno 不再可用;請直接使用 import errno 代替。請注意,這種未公開的內部匯入可能會在任何時候被刪除,即使在微版本釋出中也是如此,恕不另行通知。

C API 中的更改

函式 PySlice_GetIndicesEx() 被認為對於可調整大小的序列是不安全的。如果切片索引不是 int 的例項,而是實現 __index__() 方法的物件,則在將序列的長度傳遞給 PySlice_GetIndicesEx() 後,可以調整序列的大小。這可能導致返回超出序列長度的索引。為了避免可能的問題,請使用新的函式 PySlice_Unpack()PySlice_AdjustIndices()。(由 Serhiy Storchaka 在 bpo-27867 中貢獻。)

CPython 位元組碼更改

有兩個新的操作碼:LOAD_METHODCALL_METHOD。(由 Yury Selivanov 和 INADA Naoki 在 bpo-26110 中貢獻。)

刪除了 STORE_ANNOTATION 操作碼。(由 Mark Shannon 在 bpo-32550 中貢獻。)

僅限 Windows 的更改

用於覆蓋 sys.path 的檔案現在名為 <python-executable>._pth,而不是 'sys.path'。有關更多資訊,請參閱 查詢模組。(由 Steve Dower 在 bpo-28137 中貢獻。)

其他 CPython 實現更改

為了準備將來可能對公共 CPython 執行時初始化 API 進行的更改(有關最初但有些過時的草案,請參閱PEP 432),CPython 的內部啟動和配置管理邏輯已進行了重大重構。雖然這些更新旨在對嵌入應用程式和常規 CPython CLI 的使用者完全透明,但這裡提到它們是因為重構更改了直譯器啟動期間各種操作的內部順序,因此可能會發現以前潛在的缺陷,無論是嵌入應用程式還是 CPython 本身。(最初由 Nick Coghlan 和 Eric Snow 作為 bpo-22257 的一部分貢獻,並由 Nick、Eric 和 Victor Stinner 在其他一些問題中進一步更新)。一些受影響的已知細節

  • 由於需要在呼叫 Py_Initialize 之前建立 Unicode 物件,因此嵌入應用程式當前無法使用 PySys_AddWarnOptionUnicode()。請改用 PySys_AddWarnOption()

  • 嵌入應用程式使用 PySys_AddWarnOption() 新增的警告過濾器現在應比直譯器設定的預設過濾器具有更高的優先順序

由於預設警告過濾器的配置方式發生了更改,將 Py_BytesWarningFlag 設定為大於 1 的值已不足以既發出 BytesWarning 訊息,又將其轉換為異常。相反,必須設定標誌(以導致首先發出警告),並新增顯式的 error::BytesWarning 警告過濾器以將其轉換為異常。

由於編譯器處理文件字串的方式發生了更改,僅包含文件字串的函式體中的隱式 return None 現在被標記為與文件字串在同一行出現,而不是在函式的標題行出現。

當前的異常狀態已從幀物件移動到協程。這簡化了直譯器,並修復了在進入或退出生成器時交換異常狀態導致的一些不明顯的錯誤。(由 Mark Shannon 在 bpo-25612 中貢獻。)

Python 3.7.1 中的顯著更改

從 3.7.1 開始,Py_Initialize() 現在始終讀取並尊重與 Py_Main() 相同的全部環境設定(在早期的 Python 版本中,它尊重那些環境變數的定義不明確的子集,而在 Python 3.7.0 中,由於 bpo-34247,它沒有讀取任何環境變數)。如果不需要此行為,請在呼叫 Py_Initialize() 之前將 Py_IgnoreEnvironmentFlag 設定為 1。

在 3.7.1 中,上下文變數的 C API 已更新為使用 PyObject 指標。另請參閱 bpo-34762

在 3.7.1 中,tokenize 模組現在會在提供沒有尾隨換行符的輸入時隱式發出 NEWLINE 令牌。此行為現在與 C 令牌分析器在內部執行的操作匹配。(由 Ammar Askar 在 bpo-33899 中貢獻。)

Python 3.7.2 中的顯著更改

在 3.7.2 中,Windows 上的 venv 不再複製原始二進位制檔案,而是建立名為 python.exepythonw.exe 的重定向器指令碼。這解決了長期存在的問題,即每次 Python 更新都必須升級或重新建立所有虛擬環境。但是,請注意,此版本仍然需要重新建立虛擬環境才能獲取新指令碼。

Python 3.7.6 中的顯著更改

由於存在嚴重的安全問題,不再支援 asyncio.loop.create_datagram_endpoint()reuse_address 引數。這是因為 UDP 中的套接字選項 SO_REUSEADDR 的行為。有關更多詳細資訊,請參閱 loop.create_datagram_endpoint() 的文件。(由 Kyle Stanley、Antoine Pitrou 和 Yury Selivanov 在 bpo-37228 中貢獻。)

Python 3.7.10 中的顯著更改

早期版本的 Python 允許在 urllib.parse.parse_qs()urllib.parse.parse_qsl() 中使用 ;& 作為查詢引數分隔符。出於安全考慮,併為了符合最新的 W3C 建議,此行為已更改為僅允許使用單個分隔符,預設使用 &。此更改也會影響 cgi.parse()cgi.parse_multipart(),因為它們內部使用了受影響的函式。有關更多詳細資訊,請參閱它們各自的文件。(由 Adam Goldschmidt、Senthil Kumaran 和 Ken Jin 在 bpo-42967 中貢獻。)

Python 3.7.11 中的重要更改

一個安全修復程式更改了 ftplib.FTP 的行為,使其在設定被動資料通道時不信任遠端伺服器傳送的 IPv4 地址。我們改為重用 ftp 伺服器 IP 地址。對於需要舊行為的非常規程式碼,請在您的 FTP 例項上設定一個 trust_server_pasv_ipv4_address 屬性為 True。(請參閱 gh-87451

URL 的某些部分中存在換行符或製表符可能會導致某些形式的攻擊。按照更新 RFC 3986 的 WHATWG 規範,解析器 urllib.parse() 會從 URL 中刪除 ASCII 換行符 \n\r 和製表符 \t 字元,以防止此類攻擊。刪除的字元由新的模組級變數 urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE 控制。(請參閱 gh-88048

3.7.14 中的重要安全功能

在 2(二進位制)、4、8(八進位制)、16(十六進位制)或 32 以外的基數(例如 10(十進位制))之間轉換 intstr 時,如果字串形式的數字位數超過限制,現在會引發 ValueError,以避免由於演算法複雜性而導致的潛在拒絕服務攻擊。這是針對 CVE 2020-10735 的緩解措施。此限制可以透過環境變數、命令列標誌或 sys API 進行配置或停用。請參閱整數字符串轉換長度限制文件。字串形式的預設限制為 4300 位數字。