Python 3.7 的新特性¶
- 編輯:
Elvis Pranskevichus <elvis@magic.io>
本文解釋了 Python 3.7 相較於 3.6 的新特性。Python 3.7 於 2018 年 6 月 27 日釋出。有關詳細資訊,請參閱變更日誌。
摘要 – 版本亮點¶
新的語法特性
PEP 563,推遲型別註解的求值。
向後不相容的語法更改
新的庫模組
新的內建特性
PEP 553,新的
breakpoint()
函式。
Python 資料模型改進
標準庫的重大改進
time
模組獲得了對具有納秒級解析度的函式的支援。
CPython 實現改進
避免使用 ASCII 作為預設文字編碼
PEP 552,確定性的 .pyc
PEP 565,改進的
DeprecationWarning
處理
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-8
、C.utf8
和 UTF-8
)時,stdin
和 stdout
的預設錯誤處理程式現在是 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.stdin
和 sys.stdout
流的錯誤處理程式設定為 surrogateescape
。
強制 UTF-8 模式可用於更改嵌入式 Python 直譯器中的文字處理行為,而無需更改嵌入式應用程式的區域設定。
雖然 PEP 540 的 UTF-8 模式的優點是不管執行系統上可用的區域設定如何,它都能正常工作,但它的缺點是對擴充套件模組(例如 GNU readline
)、執行非 Python 應用程式的子程序以及執行舊版本 Python 的子程序沒有影響。為了減少與此類元件通訊時損壞文字資料的風險,Python 3.7 還實現了 PEP 540:強制 UTF-8 執行時模式)。
當區域設定為 C
或 POSIX
,並且 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 564 向 time
模組添加了六個新的“納秒”變體的時間函式
新函式將納秒數作為整數值返回。
測量結果 表明,在 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
:預設情況下僅在執行測試時顯示,適用於未來版本升級會將警告類別更改為DeprecationWarning
或FutureWarning
的情況。
以前,DeprecationWarning
和 PendingDeprecationWarning
僅在執行測試時可見,這意味著主要編寫單檔案指令碼或以互動方式使用 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_compile
或 compileall
生成。
基於雜湊的 .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-12844 和 bpo-18896 中貢獻。)
bytes.fromhex()
和bytearray.fromhex()
現在忽略所有 ASCII 空白字元,而不僅僅是空格。(由 Robert Xiao 在 bpo-28927 中貢獻。)str
、bytes
和bytearray
新增了對新的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 不同,上下文變數可以正確地支援非同步程式碼。
asyncio
和 decimal
模組已更新,可以開箱即用地使用和支援上下文變數。特別是,活動的十進位制上下文現在儲存在上下文變數中,這使得十進位制運算可以在非同步程式碼中使用正確的上下文。
另請參閱
- 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.run()
函式可以用於透過自動建立和銷燬事件迴圈來從同步程式碼執行協程。(由 Yury Selivanov 在 bpo-32314 中貢獻。)asyncio 獲得了對
contextvars
的支援。loop.call_soon()
、loop.call_soon_threadsafe()
、loop.call_later()
、loop.call_at()
和Future.add_done_callback()
有一個新的可選的僅限關鍵字的 *context* 引數。Tasks
現在會自動跟蹤它們的上下文。有關更多詳細資訊,請參閱 PEP 567。(由 Yury Selivanov 在 bpo-32436 中貢獻。)新增了
asyncio.create_task()
函式,作為asyncio.get_event_loop().create_task()
的快捷方式。(由 Andrew Svetlov 在 bpo-32311 中貢獻。)新的
loop.start_tls()
方法可用於將現有連線升級為 TLS。(由 Yury Selivanov 在 bpo-23749 中貢獻。)新的
loop.sock_recv_into()
方法允許直接將資料從套接字讀取到提供的緩衝區中,從而減少資料複製。(由 Antoine Pitrou 在 bpo-31819 中貢獻。)新的
asyncio.current_task()
函式返回當前正在執行的Task
例項,新的asyncio.all_tasks()
函式返回給定迴圈中所有現有的Task
例項的集合。Task.current_task()
和Task.all_tasks()
方法已被棄用。(由 Andrew Svetlov 在 bpo-32250 中貢獻。)新的 *臨時*
BufferedProtocol
類允許實現對接收緩衝區進行手動控制的流協議。(由 Yury Selivanov 在 bpo-32251 中貢獻。)新的
asyncio.get_running_loop()
函式返回當前正在執行的迴圈,如果沒有正在執行的迴圈,則引發RuntimeError
異常。 這與asyncio.get_event_loop()
不同,後者在沒有執行的事件迴圈時會 *建立* 一個新的事件迴圈。(由 Yury Selivanov 在 bpo-32269 中貢獻。)新的
StreamWriter.wait_closed()
協程方法允許等待直到流寫入器關閉。 新的StreamWriter.is_closing()
方法可用於確定寫入器是否正在關閉。(由 Andrew Svetlov 在 bpo-32391 中貢獻。)新的
loop.sock_sendfile()
協程方法允許在可能的情況下使用os.sendfile
傳送檔案。(由 Andrew Svetlov 在 bpo-32410 中貢獻。)新的
Future.get_loop()
和Task.get_loop()
方法返回建立任務或 future 的迴圈例項。Server.get_loop()
允許對asyncio.Server
物件執行相同的操作。(由 Yury Selivanov 在 bpo-32415 中貢獻,Srinivas Reddy Thatiparthy 在 bpo-32418 中貢獻。)現在可以控制
asyncio.Server
例項開始服務的方式。 以前,伺服器會在建立時立即開始服務。loop.create_server()
和loop.create_unix_server()
的新 *start_serving* 關鍵字引數,以及Server.start_serving()
和Server.serve_forever()
可用於解耦伺服器例項化和服務。 如果伺服器正在服務,則新的Server.is_serving()
方法返回True
。Server
物件現在是非同步上下文管理器srv = await loop.create_server(...) async with srv: # some code # At this point, srv is closed and no longer accepts new connections.
(由 Yury Selivanov 在 bpo-32662 中貢獻。)
由
loop.call_later()
返回的回撥物件獲得了新的when()
方法,該方法返回絕對計劃的回撥時間戳。(由 Andrew Svetlov 在 bpo-32741 中貢獻。)loop.create_datagram_endpoint()
方法增加了對 Unix 套接字的支援。(由 Quentin Dawans 在 bpo-31245 中貢獻。)asyncio.open_connection()
、asyncio.start_server()
函式、loop.create_connection()
、loop.create_server()
、loop.create_accepted_socket()
方法及其相應的 UNIX 套接字變體現在接受 *ssl_handshake_timeout* 關鍵字引數。(由 Neil Aspinall 在 bpo-29970 中貢獻。)如果回撥已被取消,則新的
Handle.cancelled()
方法返回True
。(由 Marat Sharafutdinov 在 bpo-31943 中貢獻。)asyncio 原始碼已轉換為使用
async
/await
語法。(由 Andrew Svetlov 在 bpo-32193 中貢獻。)新的
ReadTransport.is_reading()
方法可用於確定傳輸的讀取狀態。 此外,對ReadTransport.resume_reading()
和ReadTransport.pause_reading()
的呼叫現在是冪等的。(由 Yury Selivanov 在 bpo-32356 中貢獻。)在
asyncio
中,Linux 上的 TCP 套接字現在預設使用TCP_NODELAY
標誌建立。(由 Yury Selivanov 和 Victor Stinner 在bpo-27456中貢獻。)已取消任務中發生的異常不再被記錄。(由 Yury Selivanov 在bpo-30508中貢獻。)
新的
WindowsSelectorEventLoopPolicy
和WindowsProactorEventLoopPolicy
類。(由 Yury Selivanov 在 bpo-33792中貢獻。)
幾個 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¶
ProcessPoolExecutor
和 ThreadPoolExecutor
現在支援新的 *initializer* 和 *initargs* 建構函式引數。(由 Antoine Pitrou 在 bpo-21423 中貢獻。)
ProcessPoolExecutor
現在可以透過新的 *mp_context* 引數獲取多程序上下文。(由 Thomas Moreau 在 bpo-31540 中貢獻。)
contextlib¶
新的 nullcontext()
是比 ExitStack
更簡單、更快的空操作上下文管理器。(由 Jesse-Bakker 在 bpo-10049 中貢獻。)
新的 asynccontextmanager()
、AbstractAsyncContextManager
和 AsyncExitStack
已被新增以補充其同步對應項。(由 Jelle Zijlstra 在 bpo-29679 和 bpo-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 中貢獻。)
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¶
HTTPConnection
和 HTTPSConnection
現在支援新的 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-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 行)的輸出被壓縮成一個按鈕。可以在“設定”對話方塊的“常規”頁面的“PyShell”部分中更改 N。可以透過右鍵單擊輸出來壓縮更少但可能更長的行。可以透過雙擊按鈕將壓縮的輸出就地展開,或者透過右鍵單擊按鈕將其展開到剪貼簿或單獨的視窗中。(由 Tal Einat 在 bpo-1529353 中貢獻。)
以上更改已向後移植到 3.6 維護版本。
3.7.4 中的新功能
將“執行自定義”新增到“執行”選單,以使用自定義設定執行模組。輸入的任何命令列引數都將新增到 sys.argv。它們會在下一次自定義執行時重新出現在框中。還可以禁止正常的 Shell 主模組重新啟動。(由 Cheryl Sabella,Terry Jan Reedy 和其他人在 bpo-5680 和 bpo-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.IPv6Network
和 ipaddress.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.ASCII
、re.LOCALE
和 re.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.ForkingMixIn
和 socketserver.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-30622 和 bpo-33618 中貢獻)
SSLSocket
和 SSLObject
不再有公共建構函式。直接例項化從來都不是一個文件化和支援的功能。例項必須使用 SSLContext
方法 wrap_socket()
和 wrap_bio()
建立。(由 Christian Heimes 在 bpo-32951 中貢獻)
OpenSSL 1.1 的 API 提供了設定最小和最大 TLS 協議版本的功能,可透過 SSLContext.minimum_version
和 SSLContext.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 564 向 time
模組添加了六個具有納秒解析度的新函式
添加了新的時鐘識別符號
time.CLOCK_BOOTTIME
(Linux):與time.CLOCK_MONOTONIC
相同,但它還包括系統暫停的任何時間。time.CLOCK_PROF
(FreeBSD、NetBSD 和 OpenBSD):高解析度的按程序 CPU 計時器。time.CLOCK_UPTIME
(FreeBSD、OpenBSD):絕對值是系統執行且未暫停的時間,提供準確的正常執行時間測量的時鐘。
新的 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¶
現在可以使用新的 WrapperDescriptorType
、MethodWrapperType
、MethodDescriptorType
和 ClassMethodDescriptorType
類。(由 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_something
、bar_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-20361、bpo-32043 和 bpo-32230 中貢獻。)
棄用警告再次預設顯示在單檔案指令碼和互動式提示中。有關詳細資訊,請參閱 PEP 565: 在 __main__ 中顯示 DeprecationWarning。(由 Nick Coghlan 在 bpo-31975 中貢獻。)
xml¶
為了緩解 DTD 和外部實體檢索問題,xml.dom.minidom
和 xml.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 中貢獻。)
新的 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
的欄位 name
和 doc
現在是 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-22898 和 bpo-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()
的 start 和 end 引數現在被調整為像字串切片一樣工作。(由 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
模組為常用函式進行了許多顯著的最佳化。
asyncio.get_event_loop()
函式已用 C 重新實現,使其速度提高了 15 倍。(由 Yury Selivanov 在 bpo-32296 中貢獻。)asyncio.Future
回撥管理已得到最佳化。(由 Yury Selivanov 在 bpo-32348 中貢獻。)asyncio.gather()
現在快了 15%。(由 Yury Selivanov 在 bpo-32355 中貢獻。)當 *delay* 引數為零或負數時,
asyncio.sleep()
現在快了 2 倍。(由 Andrew Svetlov 在 bpo-32351 中貢獻。)降低了 asyncio 除錯模式的效能開銷。(由 Antoine Pitrou 在 bpo-31970 中貢獻。)
由於 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
引數是 RegexFlag
,re.compile()
現在會將它轉換為 int 物件。現在它的速度與 Python 3.5 一樣快,並且根據模式的不同,比 Python 3.6 快約 10%。(由 INADA Naoki 在 bpo-31671 中貢獻。)
在重負載下,selectors.EpollSelector
、selectors.PollSelector
和 selectors.DevpollSelector
類的 modify()
方法可能會快 10% 左右。(由 Giampaolo Rodola’ 在 bpo-30014 中貢獻。)
常量摺疊已從窺孔最佳化器移至新的 AST 最佳化器,該最佳化器能夠更一致地執行最佳化。(由 Eugene Toder 和 INADA Naoki 在 bpo-29469 和 bpo-11549 中貢獻。)
abc
中的大多數函式和方法都已用 C 重寫。這使得建立抽象基類以及在其上呼叫 isinstance()
和 issubclass()
的速度提高了 1.5 倍。這也使 Python 啟動時間減少了高達 10%。(由 Ivan Levkivskyi 和 INADA Naoki 在 bpo-31333 中貢獻。)
透過在不構造子類時使用快速路徑建構函式,顯著提高了 datetime.date
和 datetime.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_lines
和f_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 表示式(包括 yield
和 yield 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
,或設定為 0x03050400
和 0x03060000
(不包含) 之間的值,或者為 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
區域設定)中的一個,作為基於舊的ASCII
的C
區域設定的替代方案。不再支援 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 中已棄用的類Plist
、Dict
和_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.selectors
和asyncio._overlapped
。將from asyncio import selectors
替換為import selectors
。現在禁止直接例項化
ssl.SSLSocket
和ssl.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-32
和 py -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 行為的更改¶
async
和await
名稱現在是保留關鍵字。將這些名稱用作識別符號的程式碼現在會引發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-32012 和 bpo-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-31233 和 bpo-33540 中貢獻。)socketserver.ForkingMixIn.server_close()
現在會等待所有子程序完成。將新的socketserver.ForkingMixIn.block_on_close
類屬性設定為False
以獲得 3.7 之前的行為。(由 Victor Stinner 在 bpo-31151 和 bpo-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
的屬性key
、value
和coded_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()
現在接受 encoding 和 errors 引數,並返回與FieldStorage
相同的結果:對於非檔案欄位,與鍵關聯的值是字串列表,而不是位元組。(由 Pierre Quentel 在 bpo-29979 中貢獻。)由於
socket
的內部更改,不支援在舊版本 Python 中使用socket.share
建立的套接字上呼叫socket.fromshare()
。BaseException
的repr
已更改為不包括尾隨逗號。大多數異常都會受到此更改的影響。(由 Serhiy Storchaka 在 bpo-30399 中貢獻。)datetime.timedelta
的repr
已更改為在輸出中包含關鍵字引數。(由 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' 之間的空字串)。更改
re.escape()
為僅轉義正則表示式特殊字元,而不是轉義除 ASCII 字母、數字和'_'
以外的所有字元。(由 Serhiy Storchaka 在 bpo-29995 中貢獻。)tracemalloc.Traceback
幀現在按從舊到新的順序排序,以便與traceback
更加一致。(由 Jesse Bakker 在 bpo-32121 中貢獻。)在支援
socket.SOCK_NONBLOCK
或socket.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-01
到9999-12-31
範圍時,Calendar.itermonthdates
現在將一致地引發異常。 為了支援無法容忍此類異常的應用程式,可以使用新的Calendar.itermonthdays3
和Calendar.itermonthdays4
。 新方法返回元組,並且不受datetime.date
支援的範圍的限制。(由 Alexander Belopolsky 在 bpo-28292 中貢獻。)collections.ChainMap
現在保留基礎對映的順序。(由 Raymond Hettinger 在 bpo-32792 中貢獻。)現在,如果在直譯器關閉期間呼叫
concurrent.futures.ThreadPoolExecutor
和concurrent.futures.ProcessPoolExecutor
的submit()
方法,則會引發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_METHOD
和 CALL_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.exe
和 pythonw.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(十進位制))之間轉換 int
和 str
時,如果字串形式的數字位數超過限制,現在會引發 ValueError
,以避免由於演算法複雜性而導致的潛在拒絕服務攻擊。這是針對 CVE 2020-10735 的緩解措施。此限制可以透過環境變數、命令列標誌或 sys
API 進行配置或停用。請參閱整數字符串轉換長度限制文件。字串形式的預設限制為 4300 位數字。