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 – 延遲評估註解

PEP 由 Łukasz Langa 編寫和實現。

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 上發出)。此設定還將導致 Python 執行時在核心直譯器初始化時遺留 C 語言環境仍處於活動狀態時發出警告。

雖然 PEP 538 的語言環境強制轉換具有影響擴充套件模組(例如 GNU readline)以及子程序(包括執行非 Python 應用程式和舊版本 Python 的子程序)的好處,但它也有一個缺點,即要求執行系統上存在合適的ARGET語言環境。為了更好地處理沒有合適ARGET語言環境的情況(例如在 RHEL/CentOS 7 上發生的情況),Python 3.7 還實現了 PEP 540: 強制 UTF-8 執行時模式

參見

PEP 538 – 將遺留 C 語言環境強制轉換為基於 UTF-8 的語言環境

由 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 還是缺少合適的 TARGET 語言環境),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__

PEP 由 Ivan Levkivskyi 編寫和實現

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

PEP 由 Nick Coghlan 編寫和實現

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

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

參見

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

PEP 由 Ivan Levkivskyi 編寫和實現

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

Python 傳統上透過比較源元資料(上次修改時間戳和大小)與生成時快取檔案頭中儲存的源元資料來檢查位元組碼快取檔案(即 .pyc 檔案)是否最新。雖然有效,但這種失效方法有其缺點。當檔案系統時間戳過於粗糙時,Python 可能會錯過源更新,導致使用者混淆。此外,快取檔案中包含時間戳對於 可重現構建 和基於內容的構建系統來說也是一個問題。

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

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

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

參見

PEP 552 – 確定性 pyc

PEP 由 Benjamin Peterson 編寫和實現

PEP 545: Python 文件翻譯

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

已新增三個新翻譯:

參見

PEP 545 – Python 文件翻譯

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

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

  • 為了更好地支援動態建立堆疊跟蹤,types.TracebackType 現在可以從 Python 程式碼中例項化,並且 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 – 上下文變數

PEP 由 Yury Selivanov 編寫和實現

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 – 資料類

PEP 由 Eric V. Smith 編寫和實現

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 關鍵字引數。當它為真時,零用 '`' 而不是空格表示。(由 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 現在支援新的 initializerinitargs 建構函式引數。(由 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 類中的非 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 處理請求。當 http.server 使用 -m 執行S時使用它。(由 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-33642, bpo-33768, 和 bpo-33679 中貢獻。)

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

3.7.1 中的新功能

超出 N 行(預設為 50 行)的輸出會被壓縮成一個按鈕。N 可以在“設定”對話方塊的“通用”頁面的“PyShell”部分更改。透過右鍵單擊輸出,可以壓縮更少但可能過長的行。壓縮後的輸出可以透過雙擊按鈕在原地展開,或透過右鍵單擊按鈕展開到剪貼簿或單獨的視窗中。(由 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 中貢獻。)

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

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

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

io

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

ipaddress

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

itertools

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

locale

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

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

logging

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

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

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

math

新的 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 中貢獻。)

multiprocessing

新的 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() 函式允許註冊 Python 回撥,以便在程序 fork 時執行。(由 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 標誌編譯的正則表示式不再依賴於編譯時的 locale。Locale 設定僅在使用編譯後的正則表示式時應用。(由 Serhiy Storchaka 在 bpo-30215 中貢獻。)

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

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

訊號

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 引數現在接受任何 path-like object,而不僅僅是字串。(由 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-label 形式("xn--pythn-mua.org")儲存預期主機名,而不是 U-label 形式("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 設定最小和最大 TLS 協議版本的 API 可用作 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

string.Template 現在允許您選擇性地分別修改用於大括號佔位符和非大括號佔位符的正則表示式模式。(由 Barry Warsaw 在 bpo-1198569 中貢獻。)

subprocess

subprocess.run() 函式接受新的 capture_output 關鍵字引數。當為 True 時,stdout 和 stderr 將被捕獲。這等同於將 subprocess.PIPE 作為 stdoutstderr 引數傳遞。(由 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 模組現在在處理 KeyboardInterrupt 期間 subprocess.call()subprocess.run() 或在 Popen 上下文管理器中,處理得更加優雅。它現在會等待子程序退出一小段時間,然後再繼續處理 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 中貢獻。)

時間

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 屬性現在在它們被 複製pickle 後保留其標識。(由 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-20361, bpo-32043, 和 bpo-32230 中貢獻。)

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

xml

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

xml.etree

ElementPathfind() 方法中的謂詞現在可以比較當前節點的文字與 [. = "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__startimport__find__load__done 靜態標記可用於跟蹤模組匯入。(由 Christian Heimes 在 bpo-31574 中貢獻。)

結構 PyMemberDefPyGetSetDefPyStructSequence_FieldPyStructSequence_Descwrapperbase 的欄位 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 中貢獻。

透過時區建構函式 PyTimeZone_FromOffset()PyTimeZone_FromOffsetAndName() 添加了對時區的 C API 支援,並透過 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 中貢獻。)

如果第二個引數為 NULLwchar_t* 字串包含 null 字元,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-29300bpo-29507bpo-29452bpo-29286 中貢獻。)

各種最佳化使 Python 在 Linux 上的啟動時間減少了 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 中進一步改進。)

在常見情況下,datetime.date.fromordinal()datetime.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 中貢獻。)

re.compile() 現在將 flags 引數轉換為 int 物件,如果它是 RegexFlag。它現在和 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 實現更改

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

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

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

  • distutils upload 命令不再嘗試將 CR 行尾字元更改為 CRLF。這修復了以 CR 等效位元組結尾的 sdists 的損壞問題。(由 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 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

在 Python 3.4 中已棄用的方法 MetaPathFinder.find_module()(被 MetaPathFinder.find_spec() 替換)和 PathEntryFinder.find_loader()(被 PathEntryFinder.find_spec() 替換)現在都發出 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 函式和型別

如果未設定 Py_LIMITED_API 或將其設定為 0x030504000x03060000(不包括)之間,或者為 0x03060100 或更高,則函式 PySlice_GetIndicesEx() 將被棄用並替換為宏。(由 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() 的第一個引數現在只能作為位置引數傳遞。

  • 已移除在 Python 2.4 中已棄用的 plistlib 模組中的 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

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

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 的變化

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 中,Context Variables 的 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 引數。這是由於 SO_REUSEADDR 套接字選項在 UDP 中的行為。有關更多詳細資訊,請參見 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 位數字。