Python 3.7 有什么新變化?

編者

Elvis Pranskevichus <elvis@magic.io>

本文解釋了 Python 3.7 相比 3.6 的新增特性。Python 3.7 于 2018 年 6 月 27 日發(fā)布。完整的詳情可參閱 更新日志。

摘要 - 發(fā)布重點?

新的語法特性:

  • PEP 563,類型標(biāo)注延遲求值。

向后不兼容的語法更改:

  • asyncawait 現(xiàn)在是保留的關(guān)鍵字。

新的庫模塊:

新的內(nèi)置特性:

對 Python 數(shù)據(jù)模型的改進:

  • PEP 562, 自定義可訪問的模塊屬性。

  • PEP 560, typing模塊和泛型類型的核心支持。

  • dict 對象會保持插入時的順序這個特性 正式宣布 成為 Python 語言官方規(guī)范的一部分。

標(biāo)準(zhǔn)庫中的重大改進:

CPython 實現(xiàn)的改進:

C API 的改進:

  • PEP 539,用于線程本地存儲的新 C API

文檔的改進:

此版本在諸多方面有顯著的性能改進。性能優(yōu)化 章節(jié)詳細列出了它們。

和之前的 Python 版本存在兼容性的更改列表,請參閱 移植到 Python 3.7 章節(jié)。

新的特性?

PEP 563:延遲的標(biāo)注求值?

隨著 PEP 3107 加入標(biāo)注功能并在 PEP 526 進一步細化,Python 中類型提示的出現(xiàn)揭示了兩個明顯的可用性問題:

  • 標(biāo)注只能使用在當(dāng)前作用域中已經(jīng)存在的名稱,也就是說,它們不支持任何形式的前向引用;而且——

  • 標(biāo)注源碼對 Python 程序的啟動時間有不利的影響。

這兩個問題都可以通過延遲標(biāo)注求值來解決。在定義標(biāo)注的時候,編譯器并不會編譯執(zhí)行相應(yīng)表達式的代碼,而是保存與相應(yīng)表達式的 AST 等價的字符串形式。如果有需要,標(biāo)注可以在運行時使用 typing.get_type_hints() 進行解析。在不需要這種解析的通常情況下,標(biāo)注的存儲成本更低(因為解析器只需處理較短的字符串)且啟動時間更短。

在可用性方面,標(biāo)注現(xiàn)在支持向前引用,以使以下句法有效:

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

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

class B:
    ...

由于此修改會破壞兼容性,在 Python 3.7 中此種新的行為需要在每個模塊層級上使用 __future__ 導(dǎo)入來啟用:

from __future__ import annotations

它將在 Python 3.10 中成為默認行為。

參見

PEP 563 -- 延遲的標(biāo)注求值

PEP 由 ?ukasz Langa 撰寫并實現(xiàn)。

PEP 538: 傳統(tǒng) C 區(qū)域強制轉(zhuǎn)換?

Python 3 系列有一個持續(xù)的挑戰(zhàn)就是為處理 7 比特位 ASCII 文本的假定編碼確定合理的默認策略,目前的設(shè)定是在非 Windows 平臺上使用默認的 C 或 POSIX 區(qū)域設(shè)置。

PEP 538 更新了默認的解釋器命令行接口,以自動將上述區(qū)域強制轉(zhuǎn)換為可用的基于 UTF-8 的區(qū)域,具體描述可參見有關(guān)新增環(huán)境變量 PYTHONCOERCECLOCALE 的文檔。 以這種方式自動設(shè)置 LC_CTYPE 意味著核心解釋器和能感知區(qū)域的 C 擴展 (例如 readline) 都將會假定 UTF-8 已被用作默認的文本編碼,而不再是 ASCII。

PEP 11 中的平臺支持定義也已被更新以限制完整文本處理支持適當(dāng)配置的基于非 ASCII 的語言區(qū)域。

作為此更改的一部分,當(dāng)使用任何已定義的強制轉(zhuǎn)換目標(biāo)區(qū)域時 (目前為 C.UTF-8, C.utf8UTF-8) stdinstdout 默認的處理器現(xiàn)在將為 surrogateescape (而不是 strict)。 而無論是什么區(qū)域,stderr 默認的處理器仍為 backslashreplace

默認情況下區(qū)域強制轉(zhuǎn)換會靜默進行,但為了輔助調(diào)試潛在的區(qū)域相關(guān)集成問題,可以通過設(shè)置 PYTHONCOERCECLOCALE=warn 來請求顯式地啟用警告信息(直接在 stderr 上發(fā)出)。 此設(shè)置還會使得 Python 運行時在核心解釋器初始化時如果傳統(tǒng) C 區(qū)域仍然處于激活狀態(tài)時發(fā)出警告。

雖然 PEP 538 的區(qū)域強制轉(zhuǎn)換的好處在于它還會同時影響擴展模塊 (例如 GNU readline) 以及子進程 (包括運行非 Python 應(yīng)用和舊版本 Python 的子進程),但它也存在需要所運行系統(tǒng)必須存在適合的目標(biāo)區(qū)域的缺點。 為了更好地處理沒有可用適合的目標(biāo)區(qū)域的情況 (例如在 RHEL/CentOS 7 上就會出現(xiàn)此情況),Python 3.7 還實現(xiàn)了 PEP 540: 強制 UTF-8 運行時模式

參見

PEP 538 -- 強制轉(zhuǎn)換傳統(tǒng) C 區(qū)域到基于 UTF-8 的區(qū)域

PEP 由 Nick Coghlan 撰寫并實現(xiàn)。

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

新的 -X utf8 命令行選項和 PYTHONUTF8 環(huán)境變量可被用來啟用 Python UTF-8 模式

當(dāng)處于 UTF-8 模式時,CPython 會忽略區(qū)域設(shè)置,并默認使用 UTF-8 編碼。 用于 sys.stdinsys.stdout 流的錯誤處理器將設(shè)置為 surrogateescape。

強制 UTF-8 模式可被用來在嵌入的 Python 解釋器中改變文本處理行為,而不會改變嵌入方應(yīng)用的區(qū)域設(shè)置。

PEP 540 的 UTF-8 模式的好處是不必關(guān)心運行所在系統(tǒng)中有哪些可用區(qū)域即可工作,但它也存在對擴展模塊 (例如 GNU readline)、運行非 Python 應(yīng)用的子進程以及運行舊版本 Python 的子進程不起作用的缺點。 為了減小與這些組件通信時破壞文本數(shù)據(jù)的風(fēng)險,Python 3.7 還實現(xiàn)了 PEP 540: 強制 UTF-8 運行時模式)。

UTF-8 模式在語言區(qū)域為 CPOSIX 并且 PEP 538 區(qū)域強制轉(zhuǎn)換特性無法將其修改為某種基于 UTF-8 的替代項時會被默認啟用(無論修改失敗是由于設(shè)置了 PYTHONCOERCECLOCALE=0, LC_ALL 還是由于缺少適合的目標(biāo)區(qū)域)。

參見

PEP 540 -- 增加了新的 UTF-8 模式

PEP 由 Victor Stinner 撰寫并實現(xiàn)

PEP 553: 內(nèi)置的 breakpoint()?

Python 3.7 包含了新的內(nèi)置 breakpoint() 函數(shù),作為一種簡單方便地進入 Python 調(diào)試器的方式。

內(nèi)置 breakpoint() 會調(diào)用 sys.breakpointhook()。 在默認情況下后者會導(dǎo)入 pdb 然后再調(diào)用 pdb.set_trace(),但是通過將 sys.breakpointhook() 綁定到你選定的函數(shù),breakpoint() 可以進入任何調(diào)試器。 此外,環(huán)境變量 PYTHONBREAKPOINT 可被設(shè)置為你選定的調(diào)試器的可調(diào)用對象。 設(shè)置 PYTHONBREAKPOINT=0 會完全禁用內(nèi)置 breakpoint()。

參見

PEP 553 -- 內(nèi)置的 breakpoint()

PEP 由 Barry Warsaw 撰寫并實現(xiàn)

PEP 539: 用于線程局部存儲的新 C API?

雖然 Python 已提供了用于線程局部存儲支持的 C API;但原有的 線程局部存儲 (TLS) API 使用 int 來表示所有平臺上的 TLS 密鑰。 對于官方支持的平臺而言這通常不是問題,但這既不符合 POSIX 標(biāo)準(zhǔn),也不具備任何實際意義上的可移植性。

PEP 539 通過向 CPython 提供了一個新的 線程特定存儲 (TSS) API 來改變這一點,它取代了原有的 CPython 內(nèi)部 TLS API 的使用,并且原有 API 已棄用。 TSS API 使用一種新類型 Py_tss_t 而非 int 來表示 TSS 密鑰 -- 這是一種不透明類型,其定義可能依賴于下層的 TLS 實現(xiàn)。 因此,這將允許在以無法安全地轉(zhuǎn)換為 int 的方式定義原生 TLS 密鑰的平臺上構(gòu)建 CPython。

請注意在原生 TLS 密鑰定義方式無法被安全地轉(zhuǎn)換為 int 的平臺上,原有 TLS API 中的全部函數(shù)將無法執(zhí)行并會立即返回失敗信息。 這樣能清楚地表明原有 API 在無法可靠使用的平臺上不受支持,并且不會再嘗試添加此類支持。

參見

PEP 539 -- 在 CPython 中用于線程局部存儲的新 C-API

PEP 由 Erik M. Bray 撰寫;由 Masayuki Yamamoto 實現(xiàn)。

PEP 562: 定制對模塊屬性的訪問?

Python 3.7 允許在模塊上定義 __getattr__() 并且當(dāng)以其他方式找不到某個模塊屬性時將會調(diào)用它。 在模塊上定義 __dir__() 現(xiàn)在也是允許的。

一個典型的可能有用的例子是已棄用模塊屬性和惰性加載。

參見

PEP 562 -- 模塊的 __getattr____dir__

PEP 由 Ivan Levkivskyi 撰寫并實現(xiàn)

PEP 564: 具有納秒級精度的新時間函數(shù)?

現(xiàn)代系統(tǒng)的時鐘精度可以超過由 time.time() 函數(shù)及其變化形式所返回的浮點數(shù)的有限精度。 為了避免精度損失,PEP 564time 模塊中增加了原有計時器函數(shù)的六個新“納秒版”變化形式:

這些新函數(shù)會以整數(shù)值的形式返回納秒數(shù)。

Measurements show that on Linux and Windows the resolution of time.time_ns() is approximately 3 times better than that of time.time().

參見

PEP 564 -- 增加具有納秒級精度的新時間函數(shù)

PEP 由 Victor Stinner 撰寫并實現(xiàn)

PEP 565: 在 __main__ 中顯示 DeprecationWarning?

DeprecationWarning 的默認處理方式已經(jīng)被更改,這此警告默認只顯示一次,僅有當(dāng)直接在 __main__ 模塊中運行的代碼觸發(fā)它們時才會再次顯示。 因此,單文件腳本開發(fā)者以及 Python 交互模式使用者應(yīng)該會再次開始看到針對他們所使用 API 的已棄用警告,但被導(dǎo)入應(yīng)用、庫和框架模塊所觸發(fā)的已棄用警告默認將繼續(xù)隱藏。

作為此項更改的結(jié)果,標(biāo)準(zhǔn)庫現(xiàn)在允許開發(fā)者在三種不同的已棄用警告行為之間進行選擇:

  • FutureWarning: 默認情況下總是會顯示,建議用于應(yīng)用程序最終用戶應(yīng)該看到的警告信息(例如對于已棄用的應(yīng)用程序配置的設(shè)置選項)。

  • DeprecationWarning: 默認情況下僅在 __main__ 中以及當(dāng)運行測試時會顯示,建議用于其他 Python 開發(fā)者應(yīng)該看到的警告信息,提示版本升級可能導(dǎo)致行為改變或者錯誤。

  • PendingDeprecationWarning: 默認情況下僅在運行測試時會顯示,可用于提示未來版本升級將會改變警告類別為 DeprecationWarningFutureWarning 的情況。

在此之前 DeprecationWarningPendingDeprecationWarning 都僅在運行測試時可見,這意味著主要編寫單文件腳本或使用 Python 交互模式的開發(fā)者可能會因他們所用 API 突然出現(xiàn)的改變而感到驚訝。

參見

PEP 565 -- 在 __main__ 中顯示 DeprecationWarning

PEP 由 Nick Coghlan 撰寫并實現(xiàn)

PEP 560: 對 typing 模塊和泛型類型的核心支持?

PEP 484 最初的設(shè)計方式使其不會向核心 CPython 解釋器引入 任何 更改。 現(xiàn)在類型提示和 typing 模塊已被社區(qū)廣泛使用,因此這個限制已被取消。 這個 PEP 引入了兩個特殊方法 __class_getitem__()__mro_entries__,這些方法現(xiàn)在被 typing 中的大多數(shù)類和特殊構(gòu)造所使用。 結(jié)果就是與類型相關(guān)的各類操作的速度提升了 7 倍,泛型類型可以在沒有元類沖突的情況下被使用,而 typing 模塊中幾個長期存在的錯誤也已被修正。

參見

PEP 560 -- 對 typing 模塊和泛型類型的核心支持

PEP 由 Ivan Levkivskyi 撰寫并實現(xiàn)

PEP 552: 基于哈希值的 .pyc 文件?

傳統(tǒng)上 Python 檢查字節(jié)碼緩存文件 (即 .pyc 文件) 是否最新的方式是通過對源碼元數(shù)據(jù) (最后更改的時間戳和大?。┖蜕删彺鏁r保存在其文件頭中的源碼元數(shù)據(jù)進行比較。 這種檢查方法雖然有效,但也存在缺點。 當(dāng)文件系統(tǒng)的時間戳太粗糙時,Python 有可能錯過源碼更新,導(dǎo)致用戶感到困惑。 此外,在緩存文件中存在時間戳對于 構(gòu)建可再現(xiàn) 并且基于內(nèi)容的構(gòu)建系統(tǒng)來說是有問題的。

PEP 552 擴展了 pyc 格式以允許使用源文件的哈希值而非源文件的時間戳來檢查有效性。 這種 .pyc 文件就稱為“基于哈希值的”。 默認情況下,Python 仍然使用基于時間戳的有效性檢查,不會在運行時生成基于哈希值的 .pyc 文件。 基于哈希值的 .pyc 文件可以使用 py_compilecompileall 來生成。

基于哈希值的 .pyc 文件包含兩種變體:已選定和未選定。 Python 會在運行時針對相應(yīng)源碼文件驗證已選定基于哈希值的 .pyc 文件,但對未選定基于哈希值的 pyc 文件則不會這樣做。 未選定基于哈希值的 .pyc 文件對于需要由 Python 外部的系統(tǒng)(例如構(gòu)建系統(tǒng))負責(zé)使 .pyc 文件保持最新的環(huán)境來說是一種有用的性能優(yōu)化。

請參閱 已緩存字節(jié)碼的失效 了解更多信息。

參見

PEP 552 -- 確定性的 pyc 文件

PEP 由 Benjamin Peterson 撰寫并實現(xiàn)

PEP 545: Python 文檔翻譯?

PEP 545 描述了創(chuàng)建和維護 Python 文檔翻譯的整個過程。

新增了三個新的翻譯版本:

參見

PEP 545 -- Python 文檔翻譯

PEP 由 Julien Palard, Inada Naoki 和 Victor Stinner 撰寫并實現(xiàn)。

Python 開發(fā)模式 (-X dev)?

新的 -X dev 命令行選項或新的 PYTHONDEVMODE 環(huán)境變量可被用來啟用 Python 開發(fā)模式。 在開發(fā)模式下,Python 將執(zhí)行額外的如果默認啟用會導(dǎo)致開銷過大的運行時檢查。 請參閱 Python 開發(fā)模式 文檔查看完整說明。

其他語言特性修改?

  • await 表達式和包含 async for 子句的推導(dǎo)式不允許在 格式化字符串字面值 的表達式中使用。 在 Python 3.7 中此限制已被取消。

  • 現(xiàn)在可以將超過 255 個參數(shù)傳遞給一個函數(shù),而現(xiàn)在一個函數(shù)也可以擁有超過 255 個形參。 (由 Serhiy Storchaka 在 bpo-12844bpo-18896 中貢獻。)

  • 現(xiàn)在 bytes.fromhex()bytearray.fromhex() 會忽略所有 ASCII 空白符,而非僅是空格符. (由 Robert Xiao 在 bpo-28927 中貢獻。)

  • str, bytesbytearray 獲得了對新 isascii() 方法的支持,該方法可被用來測試是個字符串或字節(jié)串是否僅包含 ASCII 字符。 (由 INADA Naoki 在 bpo-32677 中貢獻。)

  • 現(xiàn)在當(dāng) from ... import ... 失敗時 ImportError 會顯示模塊名稱和模塊 __file__ 路徑。 (由 Matthias Bussonnier 在 bpo-29546 中貢獻。)

  • 現(xiàn)在已支持涉及將子模塊綁定到一個名稱的絕對導(dǎo)入的循環(huán)導(dǎo)入。 (由 Serhiy Storchaka 在 bpo-30024 中貢獻。)

  • 現(xiàn)在 object.__format__(x, '') 等價于 str(x) 而非 format(str(self), '')。 (由 Serhiy Storchaka d bpo-28974 中貢獻。)

  • 為更好地支持棧跟蹤的動態(tài)創(chuàng)建,現(xiàn)在 types.TracebackType 可以從 Python 代碼中被實例化,并且 回溯對象tb_next 屬性現(xiàn)在是可寫的。 (由 Nathaniel J. Smith 在 bpo-30579 中貢獻。)

  • 當(dāng)使用 -m 開關(guān)時,現(xiàn)在 sys.path[0] 會主動擴展為完整的起始目錄路徑,而不是保持為空目錄(這將允許在發(fā)生導(dǎo)入時從 當(dāng)前 工作目錄導(dǎo)入) (由 Nick Coghlan 在 bpo-33053 中貢獻。)

  • The new -X importtime option or the PYTHONPROFILEIMPORTTIME environment variable can be used to show the timing of each module import. (Contributed by Inada Naoki in bpo-31415.)

新增模塊?

contextvars?

新的 contextvars 模塊和一組 新的 C API 引入了對 上下文變量 的支持。 上下文變量在概念上類似于線程局部變量。 與 TLS 不同,上下文變量能正確地支持異步代碼。

asynciodecimal 已得到更新以使用和支持開箱即用的上下文變量。 特別是激活的 decimal 上下文現(xiàn)在將存儲在上下文變量中,它允許十進制運算在異步代碼中使用正確的上下文。

參見

PEP 567 -- 上下文變量

PEP 由 Yury Selivanov 撰寫并實現(xiàn)

dataclasses?

新的 dataclass() 裝飾器提供了一種聲明 數(shù)據(jù)類 的方式。 數(shù)據(jù)類使用變量標(biāo)注來描述其屬性。 它的構(gòu)造器和其他魔術(shù)方法例如 __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 -- 數(shù)據(jù)類

PEP 由 Eric V. Smith 撰寫并實現(xiàn)

importlib.resources?

新的 importlib.resources 模塊提供了一些新的 API 和一個新的 ABC 用于訪問、打開和讀取包內(nèi)的 資源。 資源基本上類似于包內(nèi)的文件,但它們不一定是物理文件系統(tǒng)中實際的文件。 模塊加載器可以提供 get_resource_reader() 函數(shù),它會返回一個 importlib.abc.ResourceReader 實例來支持這個新 API。 內(nèi)置的文件路徑加載器和 zip 文件加載器都支持此特性。

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

參見

importlib_resources -- 用于先前 Python 版本的 PyPI 下層接口。

改進的模塊?

argparse?

新的 ArgumentParser.parse_intermixed_args() 方法允許混合選項與位置參數(shù)。 (由 paul.j3 在 bpo-14191 中提供。)

asyncio?

asyncio 模塊獲得了許多新的特性、可用性和 性能提升。 重要的改變包括:

部分 asyncio API 改為 已棄用

binascii?

b2a_uu() 函數(shù)現(xiàn)在接受可選的 backtick 關(guān)鍵字參數(shù)。 當(dāng)其為真值時,零會以 '`' 而非空格來表示。 (由 Xiang Zhang 在 bpo-30103 中貢獻。)

calendar?

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

collections?

collections.namedtuple() 現(xiàn)在支持默認值。 (由 Raymond Hettinger 在 bpo-32320 中貢獻。)

compileall?

compileall.compile_dir() 增加了新的 invalidation_mode 形參,可用于啟用 基于哈希值的 .pyc 有效性檢測。 失效模式也可以在命令行中使用新的 --invalidation-mode 參數(shù)來指定。 (由 Benjamin Peterson 在 bpo-31650 中貢獻。)

concurrent.futures?

ProcessPoolExecutorThreadPoolExecutor 現(xiàn)在支持新的 初始化器 以及 initargs 構(gòu)造器參數(shù)。 (由 Antoine Pitrou 在 bpo-21423 中貢獻。)

ProcessPoolExecutor 現(xiàn)在能通過新的 mp_context 參數(shù)來接受多進程上下文。 (由 Thomas Moreau 在 bpo-31540 中貢獻。)

contextlib?

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

增加了新的 asynccontextmanager(), AbstractAsyncContextManagerAsyncExitStack 以補充它們所對應(yīng)的同步項。 (由 Jelle Zijlstra 在 bpo-29679bpo-30241 中,以及由 Alexander Mohr 和 Ilya Kulakov 在 bpo-29302 中貢獻。)

cProfile?

cProfile 命令行現(xiàn)在接受 -m module_name 作為腳本路徑的替代。 (由 Sanyam Khurana 在 bpo-21862 中貢獻。)

crypt?

crypt 模塊現(xiàn)在支持 Blowfish 哈希方法。 (由 Serhiy Storchaka 在 bpo-31664 中貢獻。)

mksalt() 函數(shù)現(xiàn)在允許指定哈希操作的輪數(shù)。 (由 Serhiy Storchaka 在 bpo-31702 中貢獻。)

datetime?

新的 datetime.fromisoformat() 方法會基于由 datetime.isoformat() 所輸出的某一特定格式字符串構(gòu)建 datetime 對象。 (由 Paul Ganssle 在 bpo-15873 中貢獻。)

tzinfo 類現(xiàn)在支持小于一分鐘的偏移量。 (由 Alexander Belopolsky 在 bpo-5288 中貢獻。)

dbm?

dbm.dumb 現(xiàn)在支持讀取只讀文件,并且在其未改變時不再寫入索引文件。

decimal?

decimal 模塊現(xiàn)在使用 上下文變量 來儲存十進制值上下文。 (由 Yury Selivanov 在 bpo-32630 中貢獻。)

dis?

dis() 函數(shù)現(xiàn)在能夠反匯編嵌套的代碼對象(推導(dǎo)式、生成器表達式和嵌套函數(shù)的代碼,以及用于構(gòu)建嵌套類的代碼)。 反匯編遞歸的最大深度由新的 depth 形參來控制。 (由 Serhiy Storchaka 在 bpo-11822 中貢獻。)

distutils?

README.rst 現(xiàn)在包含在 distutils 的標(biāo)準(zhǔn) README 列表之中,因而也包含在源碼發(fā)布之中。 (由 Ryan Gonzalez 在 bpo-11913 中貢獻。)

enum?

Enum 增加了新的 _ignore_ 類特征屬性,該屬性允許列出不應(yīng)當(dāng)成為枚舉成員的特征屬性名稱。 (由 Ethan Furman 在 bpo-31801 中貢獻。)

在 Python 3.8 中,嘗試在 Enum 類中檢查非 Enum 對象將引發(fā) TypeError (例如 1 in Color);類似地,嘗試在 Flag 成員中檢查非 Flag 對象也將引發(fā) TypeError (例如 1 in Perm.RW);目前,兩種操作均會返回 False 并且已棄用。 (由 Ethan Furman 在 bpo-33217 中貢獻。)

functools?

functools.singledispatch() 現(xiàn)在支持使用類型標(biāo)注來注冊實現(xiàn)。 (由 ?ukasz Langa 在 bpo-32227 中貢獻。)

gc?

新的 gc.freeze() 函數(shù)允許凍結(jié)由垃圾回收器所跟蹤的所有對象,并將它們從未來的集合中排除。 這可以在 POSIX fork() 調(diào)用之前使用以令 GC 友好地進行寫入時復(fù)制或加速收集。 新的 gc.unfreeze() 函數(shù)會反轉(zhuǎn)此操作。 此外,gc.get_freeze_count() 可被用于獲取凍結(jié)對象的數(shù)量。 (由 Li Zekun 在 bpo-31558 中貢獻。)

hmac?

hmac 現(xiàn)在具有經(jīng)優(yōu)化的一次性 digest() 函數(shù),其速度比 HMAC() 要快三倍。 (由 Christian Heimes 在 bpo-32433 中貢獻。)

http.client?

HTTPConnectionHTTPSConnection 現(xiàn)在支持新的 blocksize 參數(shù)以提升上傳吞吐量。 (由 Nir Soffer 在 bpo-31945 中貢獻。)

http.server?

SimpleHTTPRequestHandler 現(xiàn)在支持 HTTP If-Modified-Since 標(biāo)頭。 如果目標(biāo)文件在該標(biāo)點指定的時間之后未被修改則服務(wù)器會返回 304 響應(yīng)狀態(tài)。 (由 Pierre Quentel 在 bpo-29654 中貢獻。)

SimpleHTTPRequestHandler 接受新的 directory 參數(shù)并增加了新的 --directory 命令行參數(shù)。 通過此形參,服務(wù)器可以對服務(wù)指定目錄,默認情況下它使用當(dāng)前工作目錄。 (由 Stéphane Wirtel 和 Julien Palard 在 bpo-28707 中貢獻。)

新的 ThreadingHTTPServer 類使用線程來處理使用 ThreadingMixin 的請求。 它會在 http.server 附帶 -m 運行時被使用。 (由 Julien Palard 在 bpo-31639 中貢獻。)

idlelib 與 IDLE?

多個對自動補全的修正。 (由 Louie Lu 在 bpo-15786 中貢獻。)

Module Browser (在 File 菜單中,之前稱為 Class Browser) 現(xiàn)在會在最高層級函數(shù)和類之外顯示嵌套的函數(shù)和類。 (由 Guilherme Polo, Cheryl Sabella 和 Terry Jan Reedy 在 bpo-1612262 中貢獻。)

Settings 對話框 (Options 中的 Configure IDLE) 已經(jīng)被部分重寫以改進外觀和功能。 (由 Cheryl Sabella 和 Terry Jan Reedy 在多個問題項中貢獻。)

字體樣本現(xiàn)在包括一組非拉丁字符以便用戶能更好地查看所選特定字體的效果。 (由 Terry Jan Reedy 在 bpo-13802 中貢獻。) 樣本可以被修改以包括其他字符。 (由 Serhiy Storchaka 在 bpo-31860 中貢獻。)

之前以擴展形式實現(xiàn)的 IDLE 特性已作為正常特性重新實現(xiàn)。 它們的設(shè)置已從 Extensions 選項卡移至其他對話框選項卡。 (由 Charles Wohlganger 和 Terry Jan Reedy 在 bpo-27099 中實現(xiàn)。)

編輯器代碼上下文選項已經(jīng)過修改。 Box 會顯示所有上下文行直到最大行數(shù)。 點擊一個上下文行會使編輯器跳轉(zhuǎn)到該行。 自定義主題的上下文顏色已添加到 Settings 對話框的 Highlights 選項卡。 (由 Cheryl Sabella 和 Terry Jan Reedy 在 bpo-33642, bpo-33768bpo-33679 中貢獻。)

在 Windows 上,會有新的 API 調(diào)用將 tk 對 DPI 的調(diào)整告知 Windows。 在 Windows 8.1+ 或 10 上,如果 Python 二進制碼的 DPI 兼容屬性未改變,并且監(jiān)視器分辨率大于 96 DPI,這應(yīng)該會令文本和線條更清晰。 否則的話它應(yīng)該不造成影響。 (由 Terry Jan Reedy 在 bpo-33656 中貢獻。)

在 3.7.1 中新增:

超過 N 行(默認值為 50)的輸出將被折疊為一個按鈕。 N 可以在 Settings 對話框的 General 頁的 PyShell 部分中進行修改。 數(shù)量較少但是超長的行可以通過在輸出上右擊來折疊。 被折疊的輸出可通過雙擊按鈕來展開,或是通過右擊按鈕來放入剪貼板或是單獨的窗口。 (由 Tal Einat 在 bpo-1529353 中貢獻。)

上述修改已被反向移植到 3.6 維護發(fā)行版中。

在 3.7.4 中新增:

在 Run 菜單中增加了 "Run Customized" 以使用自定義設(shè)置來運行模塊。 輸入的任何命令行參數(shù)都會被加入 sys.argv。 它們在下次自定義運行時會再次顯示在窗體中。 用戶也可以禁用通常的 Shell 主模塊重啟。 (由 Cheryl Sabella, Terry Jan Reedy 等人在 bpo-5680bpo-37627 中貢獻。)

在 3.7.5 中新增:

在 IDLE 編輯器窗口中增加了可選的行序號。 窗口打開時默認不帶行序號,除非在配置對話框的 General 選項卡中進行設(shè)置。 已打開窗口中的行序號可以在 Options 菜單中顯示和隱藏。 (由 Tal Einat 和 Saimadhav Heblikar 在 bpo-17535 中貢獻。)

importlib?

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

如果模塊缺少規(guī)格描述 importlib.reload() 現(xiàn)在會引發(fā) ModuleNotFoundError。 (由 Garvit Khatri 在 bpo-29851 中貢獻。)

如果指定的父模塊不是一個包 (即缺少 __path__ 屬性) importlib.find_spec() 現(xiàn)在會引發(fā) ModuleNotFoundError 而非 AttributeError。 (由 Milan Oberkirch 在 bpo-30436 中貢獻。)

新的 importlib.source_hash() 可被用來計算傳入源的哈希值。 基于哈希值的 .pyc 文件 會嵌入此函數(shù)所返回的值。

io?

新的 TextIOWrapper.reconfigure() 方法可用于根據(jù)新的設(shè)置重新配置文本流。 (由 Antoine Pitrou 在 bpo-30526 以及 INADA Naoki 在 bpo-15216 中貢獻。)

ipaddress?

methods of ipaddress.IPv6Networkipaddress.IPv4Network 中新的 subnet_of() 以及 supernet_of() 方法可用于網(wǎng)絡(luò)包含測試。 (由 Michel Albert 和 Cheryl Sabella 在 bpo-20825 中貢獻。)

itertools?

itertools.islice() 現(xiàn)在接受 類整數(shù)對象 作為 start, stop 和 slice 參數(shù)。 (由 Will Roberts 在 bpo-30537 中貢獻。)

locale?

locale.format_string() 中新的 monetary 參數(shù)可用于轉(zhuǎn)換所使用的千位分隔符和分組字符串。 (由 Garvit 在 bpo-10379 中貢獻。)

現(xiàn)在 locale.getpreferredencoding() 函數(shù)在 Android 上或是在 強制 UTF-8 模式 下總是返回 'UTF-8' 。

logging?

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

新的 StreamHandler.setStream() 方法可用于在句柄創(chuàng)建之后替換日志流。 (由 Vinay Sajip 在 bpo-30522 中創(chuàng)建。)

現(xiàn)在可以在傳遞給 logging.config.fileConfig() 的配置信息中對句柄構(gòu)造器指定關(guān)鍵字參數(shù)。 (由 Preston Landers 在 bpo-31080 中貢獻。)

math?

新的 math.remainder() 函數(shù)實現(xiàn)了 IEEE 754 風(fēng)格的余數(shù)運算。 (由 Mark Dickinson 在 bpo-29962 中貢獻。)

mimetypes?

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

msilib?

新的 Database.Close() 方法可用于關(guān)閉 MSI 數(shù)據(jù)庫。 (由 Berker Peksag 在 bpo-20486 中貢獻。)

multiprocessing?

新的 Process.close() 方法會顯式地關(guān)閉進程對象并釋放與其關(guān)聯(lián)的所有資源。 如果底層進程仍在運行則將引發(fā) ValueError。 (由 Antoine Pitrou 在 bpo-30596 中貢獻。)

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

Process 所創(chuàng)建的非守護線程現(xiàn)在會在進程退出時被合并。 (由 Antoine Pitrou 在 bpo-18966 中貢獻。)

os?

os.fwalk() 現(xiàn)在接受 bytes 類型的 path 參數(shù)。 (由 Serhiy Storchaka 在 bpo-28682 中貢獻。)

os.scandir() 已獲得對 文件描述器 的支持。 (由 Serhiy Storchaka 在 bpo-25996 中貢獻。)

新的 register_at_fork() 函數(shù)允許注冊 Python 回調(diào)以便在進程分叉中執(zhí)行。 (由 Antoine Pitrou 在 bpo-16500 中貢獻。)

增加了 os.preadv() (結(jié)合了 os.readv()os.pread() 的功能) 以及 os.pwritev() 函數(shù) (結(jié)合了 os.writev()os.pwrite() 的功能)。 (由 Pablo Galindo 在 bpo-31368 中貢獻。)

os.makedirs() 的 mode 參數(shù)不再影響新創(chuàng)建的中間層級目錄的文件權(quán)限。 (由 Serhiy Storchaka 在 bpo-19930 中貢獻。)

os.dup2() 現(xiàn)在會返回新的文件描述器。 之前,返回的總是 None。 (由 Benjamin Peterson 在 bpo-32441 中貢獻。)

在 Solaris 及其派生系統(tǒng)上 os.stat() 所返回的結(jié)構(gòu)現(xiàn)在會包含 st_fstype 屬性。 (由 Jesús Cea Avión 在 bpo-32659 中貢獻。)

pathlib?

在 POSIX 類系統(tǒng)上新的 Path.is_mount() 方法現(xiàn)在可用于確定一個路徑是否為掛載點。 (由 Cooper Ry Lees 在 bpo-30897 中貢獻。)

pdb?

pdb.set_trace() 現(xiàn)在接受一個可選的限關(guān)鍵字參數(shù) header。 如果給出,它會在調(diào)試開始之前被打印到控制臺。 (由 Barry Warsaw 在 bpo-31389 中貢獻。)

pdb 命令行現(xiàn)在接受 -m module_name 作為對腳本文件的替代。 (由 Mario Corchero 在 bpo-32206 中貢獻。)

py_compile?

py_compile.compile() -- 及其擴展形式 compileall -- 現(xiàn)在會通過無條件地為基于哈希值的有效性驗證創(chuàng)建 .pyc 文件來支持 SOURCE_DATE_EPOCH 環(huán)境變量。 這樣可以確保當(dāng) .pyc 文件被主動創(chuàng)建時 可重現(xiàn)的生成。 (由 Bernhard M. Wiedemann 在 bpo-29708 中貢獻。)

pydoc?

pydoc 服務(wù)器現(xiàn)在可以綁定到由新的 -n 命令行參數(shù)所指定的任意主機名。 (由 Feanil Patel 在 bpo-31128 中貢獻。)

queue?

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

re?

旗標(biāo) re.ASCII, re.LOCALEre.UNICODE 可以在組的范圍內(nèi)設(shè)置。 (由 Serhiy Storchaka 在 bpo-31690 中貢獻。)

re.split() 現(xiàn)在支持基于匹配一個空字符串的模式例如 r'\b', '^$'(?=-) 進行拆分。 (由 Serhiy Storchaka 在 bpo-25054 中貢獻。)

使用 re.LOCALE 旗標(biāo)編譯的正則表達式不再依賴于編譯時的區(qū)域設(shè)置。 區(qū)域設(shè)置僅在已編譯正則表達式被使用時才被應(yīng)用。 (由 Serhiy Storchaka 在 bpo-30215 中貢獻。)

現(xiàn)在如果一個正則表達式包含語義將在未來發(fā)生改變的字符集構(gòu)造,則會引發(fā) FutureWarning,例如嵌套集與集合操作等。 (由 Serhiy Storchaka 在 bpo-30349 中貢獻。)

已編譯正則表達式和匹配對象現(xiàn)在可以使用 copy.copy()copy.deepcopy() 進行拷貝。 (由 Serhiy Storchaka 在 bpo-10076 中貢獻。)

signal?

signal.set_wakeup_fd() 函數(shù)新增的 warn_on_full_buffer 參數(shù)可以指定當(dāng)喚醒緩沖區(qū)溢出時 Python 是否要在 stderr 上打印警告信息。 (由 Nathaniel J. Smith 在 bpo-30050 中貢獻。)

socket?

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

新的 socket.close() 函數(shù)可關(guān)閉所傳入的套接字文件描述符。 應(yīng)該用此函數(shù)來代替 os.close() 以獲得更好的跨平臺兼容性。 (由 Christian Heimes 在 bpo-32454 中貢獻。)

socket 模塊現(xiàn)在會公開 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 中貢獻。)

套接字現(xiàn)在默認會根據(jù)文件描述符自動檢測所屬族、類型和協(xié)議。 (由 Christian Heimes 在 bpo-28134 中貢獻。)

socketserver?

socketserver.ThreadingMixIn.server_close() 現(xiàn)在會等待所有非守護線程完成。 socketserver.ForkingMixIn.server_close() 現(xiàn)在會等待所有子進程完成。

socketserver.ForkingMixInsocketserver.ThreadingMixIn 類增加了新的 socketserver.ForkingMixIn.block_on_close 類屬性。 該類屬性值設(shè)為 False 以保持 3.7 之前的行為。

sqlite3?

現(xiàn)在當(dāng)下層的 SQLite 庫版本為 3.6.11 及以上時 sqlite3.Connection 會開放 backup() 方法。 (由 Lele Gaifax 在 bpo-27645 中貢獻。)

sqlite3.connect()database 參數(shù)現(xiàn)在接受任何 path-like object,而不是只接受字符串。 (由 Anders Lorentsen 在 bpo-31843 中貢獻。)

ssl?

ssl 模塊現(xiàn)在使用 OpenSSL 的內(nèi)置 API 代替 match_hostname() 來檢查主機名或 IP 地址。 值的驗證會在 TLS 握手期間進行。 任何證書驗證錯誤包括主機名檢查失敗現(xiàn)在將引發(fā) SSLCertVerificationError 并使用正確的 TLS Alert 消息中止握手過程。 這個新異常包含有額外的信息。 主機名驗證可通過 SSLContext.hostname_checks_common_name 進行自定義。 (由 Christian Heimes 在 bpo-31399 中貢獻。)

備注

改進的主機名檢測需要有兼容 OpenSSL 1.0.2 或 1.1 的 libssl 實現(xiàn)。 因此,OpenSSL 0.9.8 和 1.0.1 不再被支持(請參閱 平臺支持的移除 了解詳情)。 目前 ssl 模塊主要兼容 LibreSSL 2.7.2 及更高版本。

ssl 模塊不再以 SNI TLS 擴展發(fā)送 IP 地址。 (由 Christian Heimes 在 bpo-32185 中貢獻。)

match_hostname() 不再支持部分通配符例如 www*.example.org。 (由 Mandeep Singh 在 bpo-23033 以及 Christian Heimes 在 bpo-31399 中貢獻。)

ssl 模塊默認的加密套件選擇現(xiàn)在是使用黑名單方式而非硬編碼的白名單。 Python 不會再重新啟用已經(jīng)被 OpenSSL 安全更新所阻止的加密。 默認的加密套件選擇可以在編譯時進行配置。 (由 Christian Heimes 在 bpo-31429 中貢獻。)

現(xiàn)在已支持包含國際化域名 (IDN) 的服務(wù)器證書驗證。 作為此更改的一部分,SSLSocket.server_hostname 屬性現(xiàn)在會以預(yù)期的 A 標(biāo)簽形式 ("xn--pythn-mua.org") 而不是以 U 標(biāo)簽形式 ("pyth?n.org") 存儲。 (由 Nathaniel J. Smith 與 Christian Heimes 在 bpo-28414 中貢獻。)

ssl 模塊對 TLS 1.3 和 OpenSSL 1.1.1 具有初步和實驗性的支持。 在 Python 3.7.0 發(fā)布的時刻,OpenSSL 1.1.1 仍在開發(fā)中,而 TLS 1.3 尚未最終確定。 TLS 1.3 握手和協(xié)議行為與 TLS 1.2 及更早的版本略有差異,請參閱 TLS 1.3。 (由 Christian Heimes 在 bpo-32947, bpo-20995, bpo-29136, bpo-30622 以及 bpo-33618 中貢獻。)

SSLSocketSSLObject 不再具有公共構(gòu)造器。 直接實例化從未成為有文檔和受支持的特性。 實際必須通過 SSLContext 的方法 wrap_socket()wrap_bio() 來創(chuàng)建。 (由 Christian Heimes 在 bpo-32951 中貢獻。)

用于設(shè)置最小和最大 TLS 協(xié)議版本的 OpenSSL 1.1 API 現(xiàn)已可用,名稱分別為 SSLContext.minimum_versionSSLContext.maximum_version。 受支持的協(xié)議由幾個新增旗標(biāo)指定,例如 HAS_TLSv1_1。 (由 Christian Heimes 在 bpo-32609 中貢獻。)

string?

string.Template 現(xiàn)在允許你有選擇地分別修改帶大括號的占位符和不帶大括號的占位符所對應(yīng)的正則表達式模式。 (由 Barry Warsaw 在 bpo-1198569 中貢獻。)

subprocess?

subprocess.run() 函數(shù)接受新的 capture_output 關(guān)鍵字參數(shù)。 當(dāng)其為真值時,將會捕獲 stdout 和 stderr。 這相當(dāng)于將 subprocess.PIPE 作為 stdoutstderr 參數(shù)傳入。 (由 Bo Bayles 在 bpo-32102 中貢獻。)

subprocess.run 函數(shù)和 subprocess.Popen 構(gòu)造器現(xiàn)在接受 text 關(guān)鍵字參數(shù)作為 universal_newlines 的別名。 (由 Andrew Clegg 在 bpo-31756 中貢獻。)

在 Windows 中當(dāng)重定向標(biāo)準(zhǔn)句柄時 close_fds 的默認值由 False 改為 True。 現(xiàn)在可以在重定向標(biāo)準(zhǔn)句柄時將 close_fds 設(shè)為真值。 參閱 subprocess.Popen。 這意味著現(xiàn)在 close_fds 在所有受支持的平臺上默認值均為 True。 (由 Segev Finer 在 bpo-19764 中貢獻。)

subprocess.call(), subprocess.run() 期間或在 Popen 上下文管理器中,subprocess 模塊現(xiàn)在能更優(yōu)雅地處理 KeyboardInterrupt。 它現(xiàn)在會等待一小段時間以便子進程退出,然后再繼續(xù)處理 KeyboardInterrupt 異常。 (由 Gregory P. Smith 在 bpo-25942 中貢獻。)

sys?

新增 sys.breakpointhook() 鉤子函數(shù),供內(nèi)置的 breakpoint() 進行調(diào)用。 (由 Barry Warsaw 在 bpo-31353 中貢獻。)

在 Android 中新增的 sys.getandroidapilevel() 會返回構(gòu)建時的 Android API 版本。 (由 Victor Stinner 在 bpo-28740 中貢獻。)

新的 sys.get_coroutine_origin_tracking_depth() 函數(shù)會返回當(dāng)前協(xié)程的由新的 sys.set_coroutine_origin_tracking_depth() 所設(shè)定的原始跟蹤深度。 asyncio 已轉(zhuǎn)換為使用這個新 API 代替已棄用的 sys.set_coroutine_wrapper()。 (由 Nathaniel J. Smith 在 bpo-32591 中貢獻。)

time?

PEP 564time 模塊增加六個具有納秒級精度的新函數(shù):

增加了新的時鐘標(biāo)識符:

  • time.CLOCK_BOOTTIME (Linux): 與 time.CLOCK_MONOTONIC 相似,不同點在于它還包括任何系統(tǒng)掛起的時間。

  • time.CLOCK_PROF (FreeBSD, NetBSD 和 OpenBSD): 高精度的分進程 CPU 計時器。

  • time.CLOCK_UPTIME (FreeBSD, OpenBSD): 該時間的絕對值是系統(tǒng)運行且未掛起的時間,提供準(zhǔn)確的正常運行時間度量。

新的 time.thread_time()time.thread_time_ns() 函數(shù)可用于獲取每線程的 CPU 時間度量。 (由 Antoine Pitrou 在 bpo-32025 中貢獻。)

新的 time.pthread_getcpuclockid() 函數(shù)會返回特定線程中 CPU 時鐘的時鐘 ID。

tkinter?

新的 tkinter.ttk.Spinbox 類現(xiàn)已可用。 (由 Alan Moore 在 bpo-32585 中貢獻。)

tracemalloc?

tracemalloc.Traceback 的行為更接近正規(guī)的回溯,會對所有幀按從最舊到最新來排序。 Traceback.format() 現(xiàn)在接受負的 limit,并會將結(jié)果截短至排在第 abs(limit) 位的舊幀。 如果要獲得舊的行為,請在 Traceback.format() 中使用新的 most_recent_first 參數(shù)。 (由 Jesse Bakker 在 bpo-32121 中貢獻。)

types?

新的 WrapperDescriptorType, MethodWrapperType, MethodDescriptorTypeClassMethodDescriptorType 類現(xiàn)已可用。 (由 Manuel Krebber 和 Guido van Rossum 在 bpo-29377 以及 Serhiy Storchaka 在 bpo-32265 中貢獻。)

新的 types.resolve_bases() 函數(shù)會以 PEP 560 所規(guī)定的方式動態(tài)解析 MRO 條目。 (由 Ivan Levkivskyi 在 bpo-32717 中貢獻。)

unicodedata?

內(nèi)部的 unicodedata 數(shù)據(jù)庫已升級為使用 Unicode 11。 (由 Benjamin Peterson 貢獻。)

unittest?

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

unittest.mock?

現(xiàn)在 sentinel 屬性會在它們被 復(fù)制封存 時保存其標(biāo)識。 (由 Serhiy Storchaka 在 bpo-20804 中貢獻。)

新的 seal() 函數(shù)允許 Mock 對實例進行密封,這將禁止進一步創(chuàng)建屬性模擬。 密封會以遞歸方式應(yīng)用于自身模擬的所有屬性。 (由 Mario Corchero 在 bpo-30541 中貢獻。)

urllib.parse?

urllib.parse.quote() 已經(jīng)從 RFC 2396 更新為 RFC 3986,將 ~ 添加到默認情況下從未引用的字符集。 (由 Christian Theune 和 Ratnadeep Debnath 在 bpo-16285 中貢獻。)

uu?

uu.encode() 函數(shù)現(xiàn)在接受可選的 backtick 關(guān)鍵字參數(shù)。 當(dāng)其為真時,零會以 '`' 而非空格來表示。 (由 Xiang Zhang 在 bpo-30103 中貢獻。)

uuid?

新的 UUID.is_safe 屬性會從平臺中繼有關(guān)是否使用多進程安全模式來生成所需 UUID 的信息。 (由 Barry Warsaw 在 bpo-22807 中貢獻。)

uuid.getnode() 現(xiàn)在更傾向于統(tǒng)一管理的 MAC 地址而不是本地管理的 MAC 地址。 這樣可以更好地保證從 uuid.uuid1() 返回的 UUID 的全局唯一性。 如果只有本地管理的 MAC 地址可用,則返回首個找到的此類地址。 (由 Barry Warsaw 在 bpo-32107 中貢獻。)

warnings?

默認警告過濾器的初始化已進行以下更改:

  • 通過命令行選項(包括 -b 以及新的 CPython 專屬的 -X dev 選項)啟用的警告總是會通過 sys.warnoptions 屬性被傳遞給警告機制。

  • 通過命令行或環(huán)境變量啟用的警告過濾器現(xiàn)在具有以下優(yōu)先順序:

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

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

    • 通過 PYTHONWARNINGS 環(huán)境變量指定的任何過濾器

    • 任何其他 CPython 專屬過濾器(例如 -X dev 模式中新增的 default 過濾器)

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

  • CPython 調(diào)試版本 中,現(xiàn)在默認情況下會顯示所有警告(隱式過濾器列表為空)

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

在單文件腳本和交互式提示符中,默認情況下會再次顯示已棄用警告。 詳情參見 PEP 565: 在 __main__ 中顯示 DeprecationWarning。 (由 Nick Coghlan 在 bpo-31975 中貢獻。)

xml.etree?

find() 方法中的 ElementPath 描述詞現(xiàn)在可以將當(dāng)前節(jié)點文本與 [. = "text"] 進行比較,而不僅是子節(jié)點中的文本。 描述詞還允許添加空格以提高可讀性。 (由 Stefan Behnel 在 bpo-31648 中貢獻。)

xmlrpc.server?

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

zipapp?

函數(shù) create_archive() 現(xiàn)在接受可選的 filter 參數(shù),以允許用戶選擇哪些文件應(yīng)被加入歸檔包。 (由 Irmen de Jong 在 bpo-31072 中貢獻。)

函數(shù) create_archive() 現(xiàn)在接受可選的 compressed 參數(shù),以生成壓縮歸檔包。 另外也加入了命令行選項 --compress 以支持壓縮。 (由 Zhiming Wang 在 bpo-31638 中貢獻。)

zipfile?

ZipFile 現(xiàn)在接受新的 compresslevel 形參,以控制壓縮級別。 (由 Bo Bayles 在 bpo-21417 中貢獻。)

ZipFile 所創(chuàng)建的歸檔包中的子目錄現(xiàn)在會按字母表順序保存。 (由 Bernhard M. Wiedemann 在 bpo-30693 中貢獻。)

C API 的改變?

已實現(xiàn)了用于線程本地存儲的新 API。 相關(guān)概述請參閱 PEP 539: 用于線程局部存儲的新 C API,完整參考文檔請查看 Thread Specific Storage (TSS) API。 (由 Masayuki Yamamoto 在 bpo-25658 中貢獻。)

新的 上下文變量 功能開放了許多 新的 C API。

新的 PyImport_GetModule() 函數(shù)會返回之前所導(dǎo)入的具有給定名稱的模塊。 (由 Eric Snow 在 bpo-28411 中貢獻。)

新的 Py_RETURN_RICHCOMPARE 宏可以簡化豐富比較函數(shù)的編寫。 (由 Petr Victorin 在 bpo-23699 中貢獻。)

新的 Py_UNREACHABLE 宏可用于標(biāo)記不可到達的代碼路徑。 (由 Barry Warsaw 在 bpo-31338 中貢獻。)

tracemalloc 現(xiàn)在通過新的 PyTraceMalloc_Track()PyTraceMalloc_Untrack() 函數(shù)公開了一個 C API。 (由 Victor Stinner 在 bpo-30054 中貢獻。)

新的 import__find__load__start()import__find__load__done() 靜態(tài)標(biāo)記可用于跟蹤模塊導(dǎo)入。 (由 Christian Heimes 在 bpo-31574 中貢獻。)

結(jié)構(gòu)體 PyMemberDef, PyGetSetDef, PyStructSequence_Field, PyStructSequence_Descwrapperbase 的字段 namedoc 現(xiàn)在的類型為 const char * 而不是 char *。 (由 Serhiy Storchaka 在 bpo-28761 中貢獻。)

PyUnicode_AsUTF8AndSize()PyUnicode_AsUTF8() 的結(jié)果類型現(xiàn)在是 const char * 而非 char *。 (由 Serhiy Storchaka 在 bpo-28769 中貢獻。)

PyMapping_Keys(), PyMapping_Values()PyMapping_Items() 的結(jié)果現(xiàn)在肯定是列表,而非可能是列表也可能是元組。 (由 Oren Milman 在 bpo-28280 中貢獻。)

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

PyOS_AfterFork() 已棄用,建議改用新的 functions PyOS_BeforeFork(), PyOS_AfterFork_Parent()PyOS_AfterFork_Child()。 (由 Antoine Pitrou 在 bpo-16500 中貢獻。)

曾經(jīng)作為公共 API 一部分的 PyExc_RecursionErrorInst 單例已被移除,因為它的成員永遠不會被清理,可能在解釋器的最終化過程中導(dǎo)致段錯誤。 由 Xavier de Gaye 在 bpo-22898bpo-30697 中貢獻。

添加 C API 對使用 timezone 的構(gòu)造器 PyTimeZone_FromOffset()PyTimeZone_FromOffsetAndName() 的時區(qū)的支持,以及通常 PyDateTime_TimeZone_UTC 使用 UTC 單例。 由 Paul Ganssle 在 bpo-10381 中貢獻。

PyThread_start_new_thread()PyThread_get_thread_ident() 的結(jié)果類型以及 PyThreadState_SetAsyncExc()id 參數(shù)類型由 long 改為 unsigned long。 (由 Serhiy Storchaka 在 bpo-6532 中貢獻。)

現(xiàn)在 PyUnicode_AsWideCharString() 如果第二個參數(shù)為 NULL 并且 wchar_t* 字符串包含空字符則會引發(fā) ValueError。 (由 Serhiy Storchaka 在 bpo-30708 中貢獻。)

對啟動順序以及動態(tài)內(nèi)存分配器管理的更改意味著早已記錄在案的,對在調(diào)用大多數(shù) C API 函數(shù)之前調(diào)用 Py_Initialize() 的要求的依賴現(xiàn)在變得更加強烈,未遵循此要求可能導(dǎo)致嵌入式應(yīng)用程序中的段錯誤。 請參閱此文檔的 移植到 Python 3.7 一節(jié)以及 C API 文檔的 在Python初始化之前 一節(jié)了解更多細節(jié)。

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

現(xiàn)在當(dāng)啟用 UTF-8 模式Py_DecodeLocale(), Py_EncodeLocale() 會使用 UTF-8 編碼。 (由 Victor Stinner 在 bpo-29240 中貢獻。)

PyUnicode_DecodeLocaleAndSize()PyUnicode_EncodeLocale() 現(xiàn)在會為 surrogateescape 錯誤句柄使用當(dāng)前區(qū)域編碼。 (由 Victor Stinner 在 bpo-29240 中貢獻。)

PyUnicode_FindChar()startend 形參的行為現(xiàn)在調(diào)整為與字符串切片類似。 (由 Xiang Zhang 在 bpo-28822 中貢獻。)

構(gòu)建的改變?

對于 --without-threads 構(gòu)建的支持已被移除。 threading 模塊現(xiàn)在將總是可用。 (由 Antoine Pitrou 在 bpo-31370 中貢獻。)

在非 OSX UNIX 平臺上已不再包含用于構(gòu)建 _ctypes 模塊的完整 libffi 副本。 現(xiàn)在當(dāng)在此類平臺上構(gòu)建 _ctypes 時需要事先裝有 libffi 的副本。 (由 Zachary Ware 在 bpo-27979 中貢獻。)

Windows 構(gòu)建過程不再依賴 Subversion 來拉取外部源碼,而是改用一段 Python 腳本從 GitHub 下載 zip 文件。 如果未在系統(tǒng)中找到 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 發(fā)布版直到 2.6.4 版還缺少所需的 OpenSSL 1.0.2 API。

性能優(yōu)化?

通過移植更多代碼來使用 METH_FASTCALL 的約定,可以顯著地減少調(diào)用 C 代碼中實現(xiàn)的各類標(biāo)準(zhǔn)庫的很多方法的開銷。 (由 Victor Stinner 在 bpo-29300、bpo-29507、bpo-29452 以及 bpo-29286 中貢獻。)

通過各種優(yōu)化方式,使 Python 在 Linux 上的啟動時間縮短了 10%,在 macOS 上縮短了 30%。 (由 Victor Stinner, INADA Naoki 在 bpo-29585 中,以及 Ivan Levkivskyi 在 bpo-31333 中貢獻。)

由于避免創(chuàng)建綁定方法案例的字節(jié)碼更改,方法調(diào)用速度現(xiàn)在加快了 20%。 (由 Yury Selivanov 和 INADA Naoki 在 bpo-26110 中貢獻。)

asyncio 模塊里面的一些常用函數(shù)做了顯著的性能優(yōu)化。

  • asyncio.get_event_loop() 函數(shù)已經(jīng)改用 C 重新實現(xiàn),使其執(zhí)行速度加快了 15 倍。 (由 Yury Selivanov 在 bpo-32296 中貢獻。)

  • asyncio.Future 回調(diào)管理已經(jīng)過優(yōu)化。 (由 Yury Selivanov 在 bpo-32348 中貢獻。)

  • asyncio.gather() 的執(zhí)行速度現(xiàn)在加快了 15%。 (由 Yury Selivanov 在 bpo-32355 中貢獻。)

  • 當(dāng) delay 參數(shù)為零或負值時 asyncio.sleep() 的執(zhí)行速度現(xiàn)在加快了 2 倍。 (由 Andrew Svetlov 在 bpo-32351 中貢獻。)

  • asyncio 調(diào)試模式的執(zhí)行開銷已獲減輕。 (由 Antoine Pitrou 在 bpo-31970 中貢獻。)

作為 PEP 560 工作 的結(jié)果,typing 的導(dǎo)入時間已減少了 7 倍,許多與類型相關(guān)的操作現(xiàn)在會執(zhí)行得更快。 (由 Ivan Levkivskyi 在 bpo-32226 中貢獻。)

sorted()list.sort() 已經(jīng)過優(yōu)化,在通常情況下執(zhí)行速度可提升 40-75%。 (由 Elliot Gorokhovsky 在 bpo-28685 中貢獻。)

dict.copy() 的執(zhí)行速度現(xiàn)在加快了 5.5 倍。 (由 Yury Selivanov 在 bpo-31179 中貢獻。)

當(dāng) name 未找到并且 obj 未重載 object.__getattr__()object.__getattribute__()hasattr()getattr() 現(xiàn)在會比原來快大約 4 倍。 (由 INADA Naoki 在 bpo-32544 中貢獻。)

在字符串中搜索特定的 Unicode 字符(例如烏克蘭語字母“?”)會比搜索其他字符慢上 25 倍。 而現(xiàn)在最壞情況下也只會慢上 3 倍。 (由 Serhiy Storchaka 在 bpo-24821 中貢獻。)

collections.namedtuple() 工廠對象已經(jīng)重寫實現(xiàn),使得創(chuàng)建具名元組的速度加快了 4 到 6 倍。 (由 Jelle Zijlstra 在 bpo-28638 中貢獻,進一步的改進由 INADA Naoki, Serhiy Storchaka 和 Raymond Hettinger 貢獻。)

現(xiàn)在 date.fromordinal()date.fromtimestamp() 在通常情況下執(zhí)行速度可提升 30%。 (由 Paul Ganssle 在 bpo-32403 中貢獻。)

由于使用了 os.scandir(),現(xiàn)在 os.fwalk() 函數(shù)執(zhí)行速度提升了 2 倍。 (由 Serhiy Storchaka 在 bpo-25996 中貢獻。)

由于使用了 os.scandir() 函數(shù),shutil.rmtree() 函數(shù)的執(zhí)行速度已經(jīng)提升了 20--40%。 (由 Serhiy Storchaka 在 bpo-28564 中貢獻。)

正則表達式 忽略大小寫的匹配和搜索已獲得優(yōu)化。 現(xiàn)在搜索某些模式的速度提升了 20 倍。 (由 Serhiy Storchaka 在 bpo-30285 中貢獻。)

re.compile() 現(xiàn)在會將 flags 形參轉(zhuǎn)換為 int 對象,如果它是 RegexFlag 的話。 它現(xiàn)在會和 Python 3.5 一樣快,而比 Python 3.6 快大約 10%,實際速度取決于具體的模式。 (由 INADA Naoki 在 bpo-31671 中貢獻。)

selectors.EpollSelector, selectors.PollSelectorselectors.DevpollSelector 這幾個類的 modify() 方法在重負載下可以加快 10% 左右。 (由 Giampaolo Rodola' 在 bpo-30014 中貢獻。)

常量折疊已經(jīng)從窺孔優(yōu)化器遷移至新的 AST 優(yōu)化器,后者可以以更高的一致性來執(zhí)行優(yōu)化。 (由 Eugene Toder 和 INADA Naoki 在 bpo-29469bpo-11549 中貢獻。)

abc 中的大部分函數(shù)和方法已經(jīng)用 C 重寫。 這使得創(chuàng)建抽像基類以及調(diào)用其 isinstance()issubclass() 的速度加快了 1.5 倍。 這也使得 Python 啟動耗時減少了 10%。 (由 Ivan Levkivskyi 和 INADA Naoki 在 bpo-31333 中貢獻。)

在不構(gòu)造子類時,通過使用快速路徑構(gòu)造器使得 datetime.datedatetime.datetime 的替代構(gòu)造器獲得了顯著的速度提升。 (由 Paul Ganssle 在 bpo-32403 中貢獻。)

在特定情況下 array.array 實例的比較速度已獲得很大提升。 現(xiàn)在當(dāng)比較存放相同的整數(shù)類型的值的數(shù)組時會比原來快 10 到 70 倍。 (由 Adrian Wielgosik 在 bpo-24700 中貢獻。)

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

其他 CPython 實現(xiàn)的改變?

  • 跟蹤鉤子現(xiàn)在可以選擇不接收 line 而是選擇從解釋器接收 opcode 事件,具體做法是在被跟蹤的幀上相應(yīng)地設(shè)置新的 f_trace_linesf_trace_opcodes 屬性。 (由 Nick Coghlan 在 bpo-31344 中貢獻。)

  • 修復(fù)了一些命名空間包模塊屬性的一致性問題。 命名空間模塊對象的 __file__ 被設(shè)置為 None (原先未設(shè)置),對象的 __spec__.origin 也被設(shè)置為 None (之前為字符串 "namespace")。 參見 bpo-32305。 而且,命名空間模塊對象的 __spec__.loader 被設(shè)置的值與 __loader__ 相同 (原先前者被設(shè)置為 None)。 參見 bpo-32303

  • locals() 字典現(xiàn)在以變量定義的詞法順序顯示。 原先未定義順序。 (由 Raymond Hettinger 在 bpo-32690 中貢獻。)

  • distutils upload 命令不會再試圖將行結(jié)束字符 CR 改為 CRLF。 這修復(fù)了 sdists 的一個以與 CR 等價的字節(jié)結(jié)束的數(shù)據(jù)損壞問題。 (由 Bo Bayles 在 bpo-32304 中貢獻。)

已棄用的 Python 行為?

在推導(dǎo)式和生成器表達式中的 yield 語句(包括 yieldyield from 子句)現(xiàn)在已棄用(最左端的 for 子句中的可迭代對象表達式除外)。 這確保了推導(dǎo)式總是立即返回適當(dāng)類型的容器(而不是有可能返回 generator iterator 對象),這樣生成器表達式不會試圖將它們的隱式輸出與任何來自顯式 yield 表達式的輸出交錯起來。 在 Python 3.7 中,這樣的表達式會在編譯時引發(fā) DeprecationWarning,在 Python 3.8 中則將引發(fā) SyntaxError。 (由 Serhiy Storchaka 在 bpo-10544 中貢獻。)

object.__complex__() 返回一個 complex 的子類的行為已棄用并將在未來的 Python 版本中引發(fā)錯誤。 這使得 __complex__() 的行為與 object.__int__()object.__float__() 保持一致。 (由 Serhiy Storchaka 在 bpo-28894 中貢獻。)

已棄用的 Python 模塊、函數(shù)和方法?

aifc?

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

asyncio?

asyncio.Lock 和其他 asyncio 同步原語的 await 實例的直接支持已棄用。 想要獲取并釋放同步資源必須使用異步上下文管理器。 (由 Andrew Svetlov 在 bpo-32253 中貢獻。)

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

collections?

在 Python 3.8 中,collections.abc 內(nèi)的抽象基類將不會再通過常規(guī)的 collections 模塊公開。 這有助于更清晰地區(qū)別具體類與抽象基類。 (由 Serhiy Storchaka 在 bpo-25988 中貢獻。)

dbm?

dbm.dumb 現(xiàn)在支持讀取只讀文件,且當(dāng)其未被更改時不會再寫入索引文件。 現(xiàn)在如果索引文件丟失并在 'r''w' 模式下被重新創(chuàng)建,則會發(fā)出已棄用警告(在未來的 Python 發(fā)布版中將改為錯誤)。 (由 Serhiy Storchaka 在 bpo-28847 中貢獻。)

enum?

在 Python 3.8 中,嘗試在 Enum 類中檢查非 Enum 對象將引發(fā) TypeError (例如 1 in Color);類似地,嘗試在 Flag 成員中檢查非 Flag 對象也將引發(fā) TypeError (例如 1 in Perm.RW);目前,兩種操作均會返回 False。 (由 Ethan Furman 在 bpo-33217 中貢獻。)

gettext?

使用非整數(shù)值在 gettext 中選擇復(fù)數(shù)形式現(xiàn)在已棄用。 它從未正確地發(fā)揮作用。 (由 Serhiy Storchaka 在 bpo-28692 中貢獻。)

importlib?

下列方法 MetaPathFinder.find_module() (被 MetaPathFinder.find_spec() 替代) 和 PathEntryFinder.find_loader() (被 PathEntryFinder.find_spec() 替代) 都在 Python 3.4 中已棄用,現(xiàn)在會引發(fā) DeprecationWarning。 (由 Matthias Bussonnier 在 bpo-29576 中貢獻)

importlib.abc.ResourceLoader ABC 已棄用,推薦改用 importlib.abc.ResourceReader。

locale?

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

macpath?

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

threading?

dummy_threading_dummy_thread 已棄用。 構(gòu)建禁用線程的 Python 已不再可能。 請改用 threading。 (由 Antoine Pitrou 在 bpo-31370 中貢獻。)

socket?

socket.htons()socket.ntohs() 中的靜默參數(shù)截斷已棄用。 在未來的 Python 版本中,如果傳入的參數(shù)長度大于 16 比特位,將會引發(fā)異常。 (由 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() 函數(shù)已棄用并將在未來的 Python 版本中被移除。 (由 Victor Stinner 在 bpo-28799 中貢獻。)

wave?

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

已棄用的 C API 函數(shù)和類型?

如果 Py_LIMITED_API 未設(shè)定或設(shè)定為范圍在 0x030504000x03060000 (不含) 之間,或為 0x03060100 或更高的值,函數(shù) PySlice_GetIndicesEx() 已棄用并被一個宏所替代。 (由 Serhiy Storchaka 在 bpo-27867 中貢獻。)

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

平臺支持的移除?

  • 官方已不再支持 FreeBSD 9 及更舊的版本。

  • 為了完整的 Unicode 支持,包括在擴展模塊之內(nèi),*nix 平臺現(xiàn)在至少應(yīng)當(dāng)提供 C.UTF-8 (完整區(qū)域), C.utf8 (完整區(qū)域) 或 UTF-8 (LC_CTYPE 專屬區(qū)域) 中的一個作為基于 ASCII 的傳統(tǒng) C 區(qū)域的替代。

  • OpenSSL 0.9.8 和 1.0.1 已不再受支持,這意味著在仍然使用這些版本的舊平臺上構(gòu)建帶有 SSL/TLS 支持的 CPython 3.7 時,需要自定義構(gòu)建選項以鏈接到更新的 OpenSSL 版本。

    注意,此問題會影響到 Debian 8 (代號“jessie”) 和 Ubuntu 14.04 (代號“Trusty”) 等長期支持 Linux 發(fā)行版,因為它們默認仍然使用 OpenSSL 1.0.1。

    Debian 9 (“stretch”) 和 Ubuntu 16.04 (“xenial”) 以及其他最新的長期支持 Linux 發(fā)行版 (例如 RHEL/CentOS 7.5, SLES 12-SP3) 都使用 OpenSSL 1.0.2 或更新的版本,因此繼續(xù)在默認的構(gòu)建配置中受到支持。

    CPython 自己的 CI 配置文件 提供了一個使用 CPython 測試套件中的 SSL 兼容性測試架構(gòu) 基于 OpenSSL 1.1.0 進行構(gòu)建和鏈接的例子,而不是使用過時的系統(tǒng)所提供的 OpenSSL。

API 與特性的移除?

下列特性與 API 已從 Python 3.7 中移除:

  • os.stat_float_times() 函數(shù)已被移除。 它在 Python 2.3 中被引入用于向下兼容 Python 2.2,并自 Python 3.1 起就已棄用。

  • re.sub() 的替換模塊中由 '\' 與一個 ASCII 字母構(gòu)成的未知轉(zhuǎn)義在 Python 3.5 中已棄用,現(xiàn)在將會引發(fā)錯誤。

  • tarfile.TarFile.add() 中移除了對 exclude 參數(shù)的支持。 它在 Python 2.7 和 3.2 中已棄用。 請改用 filter 參數(shù)。

  • ntpath 模塊中的 splitunc() 函數(shù)在 Python 3.1 中已棄用,現(xiàn)在已被移除。 請改用 splitdrive() 函數(shù)。

  • collections.namedtuple() 不再支持 verbose 形參或 _source 屬性,該屬性會顯示為具名元組類所生成的源代碼。 這是加速類創(chuàng)建的設(shè)計優(yōu)化的一部分。 (由 Jelle Zijlstra 在 bpo-28638 中貢獻,進一步的改進由 INADA Naoki, Serhiy Storchaka 和 Raymond Hettinger 貢獻。)

  • 函數(shù) bool(), float(), list()tuple() 不再接受關(guān)鍵字參數(shù)。 int() 的第一個參數(shù)現(xiàn)在只能作為位置參數(shù)傳入。

  • 移除了之前在 Python 2.4 中已棄用的 plistlib 模塊的類 Plist, Dict_InternalDict。 作為函數(shù) readPlist()readPlistFromBytes() 返回結(jié)果的 Dict 值現(xiàn)在為普通 dict。 你不能再使用屬性訪問來獲取這些字典的項。

  • asyncio.windows_utils.socketpair() 函數(shù)已被移除。 請改用 socket.socketpair() 函數(shù),它自 Python 3.5 起就在所有平臺上可用。 asyncio.windows_utils.socketpair 在 Python 3.5 及更新版本上只是 socket.socketpair 的別名。

  • asyncio 不再將 selectors_overlapped 模塊導(dǎo)出為 asyncio.selectorsasyncio._overlapped。 請將 from asyncio import selectors 替換為 import selectors。

  • 現(xiàn)在已禁止直接實例化 ssl.SSLSocketssl.SSLObject 對象。 相應(yīng)構(gòu)造器從未寫入文檔、也從未作為公有構(gòu)造器進行測試或設(shè)計。 用戶應(yīng)當(dāng)使用 ssl.wrap_socket()ssl.SSLContext。 (由 Christian Heimes 在 bpo-32951 中貢獻。)

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

移除的模塊?

fpectl 模塊已被移除。 它從未被默認啟用,從未在 x86-64 上正確發(fā)揮效果,并且它對 Python ABI 的改變會導(dǎo)致 C 擴展的意外損壞。 (由 Nathaniel J. Smith 在 bpo-29137 中貢獻。)

Windows 專屬的改變?

Python 啟動器(py.exe)可以接受 32 位或 64 位標(biāo)記而 不必 同時指定一個小版本。 因此 py -3-32py -3-64py -3.7-32 均為有效,并且現(xiàn)在還接受 -m-64 和 -m.n-64 來強制使用 64 位 python 命令,即使是本應(yīng)使用 32 位的時候。 如果指定版本不可用則 py.exe 將報錯退出。 (由 Steve Barnes 在 bpo-30291 中貢獻。)

啟動器可以運行 py -0 來列出已安裝的所有 python,默認版本會以星號標(biāo)出。 運行 py -0p 將同時列出相應(yīng)的路徑。 如果運行 py 時指定了無法匹配的版本,它將顯示 簡短形式 的可用版本列表。 (由 Steve Barnes 在 bpo-30362 中貢獻。)

移植到 Python 3.7?

本節(jié)列出了先前描述的更改以及可能需要更改代碼的其他錯誤修正.

Python 行為的更改?

  • asyncawait 現(xiàn)在是保留關(guān)鍵字。 使用了這些名稱作為標(biāo)識符的代碼現(xiàn)在將引發(fā) SyntaxError。 (由 Jelle Zijlstra 在 bpo-30406 中貢獻。)

  • PEP 479 在 Python 3.7 中對所有代碼啟用,在協(xié)程和生成器中直接或間接引發(fā)的 StopIteration 異常會被轉(zhuǎn)換為 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
    

    現(xiàn)在 Python 3.7 會正確地引發(fā) SyntaxError,因為生成器表達式總是必須直接包含于一對括號之內(nèi), 且前后都不能有逗號,僅在調(diào)用時可以忽略重復(fù)的括號。 (由 Serhiy Storchaka 在 bpo-32012bpo-32023 中貢獻。)

  • 現(xiàn)在當(dāng)使用 -m 開關(guān)時,會將初始工作目錄添加到 sys.path,而不再是一個空字符串(即在每次導(dǎo)入時動態(tài)地指明當(dāng)前工作目錄)。 任何會檢測該空字符串,或是以其他方式依賴之前行為的的程序?qū)⑿枰M行相應(yīng)的更新(例如改為還要檢測 os.getcwd()os.path.dirname(__main__.__file__),具體做法首先要取決于為何要對代碼執(zhí)行空字符串檢測)。

Python API 的變化?

  • socketserver.ThreadingMixIn.server_close() 現(xiàn)在會等待所有非守護線程完成。 將新增的 socketserver.ThreadingMixIn.block_on_close 類屬性設(shè)為 False 可獲得 3.7 之前版本的行為。 (由 Victor Stinner 在 bpo-31233bpo-33540 中貢獻。)

  • socketserver.ForkingMixIn.server_close() 現(xiàn)在會等等所有子進程完成。 將新增的 socketserver.ForkingMixIn.block_on_close 類屬性設(shè)為 False 可獲得 3.7 之前版本的行為。 (由 Victor Stinner 在 bpo-31151bpo-33540 中貢獻。)

  • 某些情況下 locale.localeconv() 函數(shù)現(xiàn)在會臨時將 LC_CTYPE 區(qū)域設(shè)置為 LC_NUMERIC 的值。 (由 Victor Stinner 在 bpo-31900 中貢獻。)

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

  • string.Formatter.format() 的格式字符串參數(shù)現(xiàn)在為 僅限位置 參數(shù)。 將其作為關(guān)鍵字參數(shù)傳入的方式自 Python 3.5 起已棄用。 (由 Serhiy Storchaka 在 bpo-29193 中貢獻。)

  • http.cookies.Morsel 的屬性 key, valuecoded_value 現(xiàn)在均為只讀。 對其賦值的操作自 Python 3.5 起已棄用。 要設(shè)置它們的值請使用 set() 方法。 (由 Serhiy Storchaka 在 bpo-29192 中貢獻。)

  • os.makedirs()mode 參數(shù)不會再影響新建中間層級目錄的文件權(quán)限位。 要設(shè)置它們的文件權(quán)限位你可以在發(fā)起調(diào)用 makedirs() 之前設(shè)置 umask。 (由 Serhiy Storchaka 在 bpo-19930 中貢獻。)

  • struct.Struct.format 的類型現(xiàn)在是 str 而非 bytes。 (由 Victor Stinner 在 bpo-21071 中貢獻。)

  • parse_multipart() 現(xiàn)在接受 encodingerrors 參數(shù)并返回與 FieldStorage 同樣的結(jié)果:對于非文件字段,與鍵相關(guān)聯(lián)的值是一個字符串列表,而非字節(jié)串。 (由 Pierre Quentel 在 bpo-29979 中貢獻。)

  • 由于 socket 中的內(nèi)部更改,在由舊版 Python 中的 socket.share 所創(chuàng)建的套接字上調(diào)用 socket.fromshare() 已不受支持。

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

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

  • 因為 shutil.rmtree() 現(xiàn)在是使用 os.scandir() 函數(shù)實現(xiàn)的,用戶指定的句柄 onerror 現(xiàn)在被調(diào)用時如果列目錄失敗會附帶第一個參數(shù) os.scandir 而不是 os.listdir。

  • 未來可能加入在正則表達式中對 Unicode 技術(shù)標(biāo)準(zhǔn) #18 中嵌套集合與集合操作的支持。 這會改變現(xiàn)有語法。 為了推動這項未來的改變,目前在有歧義的情況下會引發(fā) FutureWarning。 這包括以字面值 '[' 開頭或包含字面值字符序列 '--', '&&', '~~' 以及 '||' 的集合。 要避免警告,請用反斜杠對其進行轉(zhuǎn)義。 (由 Serhiy Storchaka 在 bpo-30349 中貢獻。)

  • 基于可以匹配空字符串的 正則表達式 對字符串進行拆分的結(jié)果已被更改。 例如基于 r'\s*' 的拆分現(xiàn)在不僅會像原先那樣拆分空格符,而且會拆分所有非空格字符之前和字符串結(jié)尾處的空字符串。 通過將模式修改為 r'\s+' 可以恢復(fù)原先的行為。 自 Python 3.5 開始此類模式將會引發(fā) FutureWarning。

    對于同時匹配空字符串和非空字符串的模式,在其他情況下搜索所有匹配的結(jié)果也可能會被更改。 例如在字符串 'a\n\n' 中,模式 r'(?m)^\s*?$' 將不僅會匹配位置 2 和 3 上的空字符串,還會匹配位置 2--3 上的字符串 '\n'。 想要只匹配空行,模式應(yīng)當(dāng)改寫為 r'(?m)^[^\S\n]*$'。

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

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

  • re.escape() 更改為只轉(zhuǎn)義正則表達式特殊字符,而不轉(zhuǎn)義 ASCII 字母、數(shù)字和 '_' 以外的所有字符。 (由 Serhiy Storchaka 在 bpo-29995 中貢獻。)

  • tracemalloc.Traceback 幀現(xiàn)在是按從最舊到最新排序,以便與 traceback 更為一致。 (由 Jesse Bakker 在 bpo-32121 中貢獻。)

  • 在支持 socket.SOCK_NONBLOCKsocket.SOCK_CLOEXEC 標(biāo)志位的操作系統(tǒng)上,socket.type 不再應(yīng)用它們。 因此,像 if sock.type == socket.SOCK_STREAM 之類的檢測會在所有平臺上按預(yù)期的方式工作。 (由 Yury Selivanov 在 bpo-32331 中貢獻。)

  • 在 Windows 上當(dāng)重定向標(biāo)準(zhǔn)句柄時,subprocess.Popenclose_fds 參數(shù)的默認值從 False 更改為 True。 如果你以前依賴于在使用帶有標(biāo)準(zhǔn) io 重定向的 subprocess.Popen 時所繼承的句柄,則必須傳入 close_fds=False 以保留原先的行為,或是使用 STARTUPINFO.lpAttributeList

  • importlib.machinery.PathFinder.invalidate_caches() -- 此方法隱式地影響 importlib.invalidate_caches() -- 現(xiàn)在會刪除 sys.path_importer_cache 中被設(shè)為 None 的條目。 (由 Brett Cannon 在 bpo-33169 中貢獻。)

  • asyncio 中,loop.sock_recv(), loop.sock_sendall(), loop.sock_accept(), loop.getaddrinfo(), loop.getnameinfo() 已被更改為正確的協(xié)程方法以與培訓(xùn)五日文檔相匹配。 之前,這些方法會返回 asyncio.Future 實例。 (由 Yury Selivanov 在 bpo-32327 中貢獻。)

  • asyncio.Server.sockets 現(xiàn)在會返回服務(wù)器套接字列表的副本,而不是直接地返回它。 (由 Yury Selivanov 在 bpo-32662 中貢獻。)

  • Struct.format 現(xiàn)在是一個 str 實例而非 bytes 實例。 (由 Victor Stinner 在 bpo-21071 中貢獻。)

  • 現(xiàn)在可以通過將 required=True 傳給 ArgumentParser.add_subparsers() 使得 argparse 子解析器成為必需的。 (由 Anthony Sottile 在 bpo-26510 中貢獻。)

  • ast.literal_eval() 現(xiàn)在更為嚴格。 任意地加減數(shù)字已不再被允許。 (由 Serhiy Storchaka 在 bpo-31778 中貢獻。)

  • 當(dāng)一個日期超出 0001-01-019999-12-31 范圍時 Calendar.itermonthdates 現(xiàn)在將始終如一地引發(fā)異常,以便支持不能容忍此類異常的應(yīng)用程序,可以使用新增的 Calendar.itermonthdays3Calendar.itermonthdays4。 這些新方法返回元組,并且其不受 datetime.date 所支持的范圍限制。 (由 Alexander Belopolsky 在 bpo-28292 中貢獻。)

  • collections.ChainMap 現(xiàn)在會保留底層映射的順序。 (由 Raymond Hettinger 在 bpo-32792 中貢獻。)

  • 如果在解釋器關(guān)閉期間被調(diào)用,concurrent.futures.ThreadPoolExecutorconcurrent.futures.ProcessPoolExecutorsubmit() 方法現(xiàn)在會引發(fā) RuntimeError。 (由 Mark Nemec 在 bpo-33097 中貢獻。)

  • configparser.ConfigParser 構(gòu)造器現(xiàn)在使用 read_dict() 來處理默認值,以使其行為與解析器的其余部分保持致。 在默認字典中的非字符串鍵和值現(xiàn)在會被隱式地轉(zhuǎn)換為字符串。 (由 James Tocknell 在 bpo-23835 中貢獻。)

  • 一些未寫入文檔的內(nèi)部導(dǎo)入已被移除。 一個例子是 os.errno 已不再可用;應(yīng)改為直接使用 import errno。 請注意此類未寫入文檔的內(nèi)部導(dǎo)入可能未經(jīng)通知地隨時被移除,甚至是在微版本號發(fā)行版中移除。

C API 的變化?

函數(shù) PySlice_GetIndicesEx() 被認為對于大小可變的序列來說并不安全。 如果切片索引不是 int 的實例,而是實現(xiàn)了 __index__() 方法的對象,則序列可以在其長度被傳給 !PySlice_GetIndicesEx 之后調(diào)整大小。 這可能導(dǎo)致返回超出序列長度的索引號。 為了避免可能的問題,請使用新增的函數(shù) PySlice_Unpack()PySlice_AdjustIndices()。 (由 Serhiy Storchaka 在 bpo-27867 中貢獻。)

CPython 字節(jié)碼的改變?

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

STORE_ANNOTATION 操作碼已被移除。 (由 Mark Shannon 在 bpo-32550 中貢獻。)

Windows 專屬的改變?

The file used to override sys.path is now called <python-executable>._pth instead of 'sys.path'. See 查找模塊 for more information. (Contributed by Steve Dower in bpo-28137.)

其他 CPython 實現(xiàn)的改變?

為了準(zhǔn)備在未來對公開的 CPython 運行時初始化 API 進行潛在更改(請參閱 PEP 432 獲取最初但略為過時的文稿),CPython 內(nèi)部的啟動和配置管理邏輯已經(jīng)過大幅重構(gòu)。 雖然這些更新旨在對嵌入式應(yīng)用程序和常規(guī)的 CPython CLI 用戶都完全透明,但它們在這里被提及是因為重構(gòu)會改變解釋器啟動期間許多操作的內(nèi)部順序,因此可能提示出原先隱藏的缺陷,這可能存在于嵌入式應(yīng)用程序中,或是在 CPython 自身內(nèi)部。 (最初由 Nick Coghlan 和 Eric Snow 作為 bpo-22257 的一部分貢獻,并由 Nick, Eric 和 Victor Stinner 在一系列其他問題報告中進一步更新)。 已知會受到影響的一些細節(jié):

  • PySys_AddWarnOptionUnicode() 目前對嵌入式應(yīng)用程序不可用,因為在調(diào)用 Py_Initialize 之前需要創(chuàng)建 Unicode 對象。 請改用 PySys_AddWarnOption()

  • 嵌入式應(yīng)用程序通過 PySys_AddWarnOption() 所添加的警告過濾器現(xiàn)在應(yīng)該以更高的一致性優(yōu)先于由解釋器所設(shè)置的默認過濾器

由于默認警告過濾器的配置方式發(fā)生了變化,將 Py_BytesWarningFlag 設(shè)置為大于一的值不再足以在發(fā)出 BytesWarning 消息的同時將其轉(zhuǎn)換為異常。 而是改為必須設(shè)置旗標(biāo)(以便首先發(fā)出警告),以及添加顯式的 error::BytesWarning 警告過濾器來將其轉(zhuǎn)換為異常。

由于編譯器處理文檔字符串的方式發(fā)生了變化,一個僅由文檔字符串構(gòu)成的函數(shù)體中隱式的 return None 現(xiàn)在被標(biāo)記為在與文檔字符串相同的行,而不是在函數(shù)的標(biāo)題行。

當(dāng)前異常狀態(tài)已從幀對象移到協(xié)程對象。 這會簡化解釋器并修正由于在進入或退出生成器時具有交換異常狀態(tài)而導(dǎo)致的一些模糊錯誤。 (由 Mark Shannon 在 bpo-25612 中貢獻。)

Python 3.7.1 中的重要變化?

從 3.7.1 開始,Py_Initialize() 現(xiàn)在始終會讀取并遵循與 Py_Main() 相同的環(huán)境設(shè)置(在更早的 Python 版本中,它會遵循一個錯誤定義的環(huán)境變量子集,而在 Python 3.7.0 中則會由于 bpo-34247 而完全不讀取它們)。 如果不想要此行為,請在調(diào)用 Py_Initialize() 之前將 Py_IgnoreEnvironmentFlag 設(shè)為 1。

在 3.7.1 中,上下文變量的 C API 已 獲得更新 以使用 PyObject 指針。 另請參閱 bpo-34762。

在 3.7.1 中,當(dāng)提供不帶末尾新行的輸入時 tokenize 模塊現(xiàn)在會隱式地添加 NEWLINE 形符。 此行為現(xiàn)在已與 C 詞法分析器的內(nèi)部行為相匹配。 (由 Ammar Askar 在 bpo-33899 中貢獻。)

Python 3.7.2 中的重要變化?

在 3.7.2 中,Windows 下的 venv 不再復(fù)制原來的二進制文件,而是改為創(chuàng)建名為 python.exepythonw.exe 的重定向腳本。 這解決了一個長期存在的問題,即所有虛擬環(huán)境在每次 Python 升級后都必須進行升級或是重新創(chuàng)建。 然而,要注意此發(fā)布版仍然要求重新創(chuàng)建虛擬環(huán)境以獲得新的腳本。

Python 3.7.6 中的重要變化?

出于重要的安全性考量,asyncio.loop.create_datagram_endpoint()reuse_address 形參不再被支持。 這是由 UDP 中的套接字選項 SO_REUSEADDR 的行為導(dǎo)致的。 更多細節(jié)請參閱 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() 中 query 形參的分隔鍵。 出于安全考慮,也為了遵循更新的 W3C 推薦設(shè)置,這已被改為只允許單個分隔鍵,默認為 &。 這一改變還會影響 cgi.parse()cgi.parse_multipart() 因為它們在內(nèi)部使用了受影響的函數(shù)。 要了解更多細節(jié),請查看它們各自的文檔。 (由 Adam Goldschmidt, Senthil Kumaran 和 Ken Jin 在 bpo-42967 中貢獻。)