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 數據模型的改進:
標準庫中的重大改進:
CPython 實現的改進:
避免使用 ASCII 作為默認的文本編碼:
PEP 552,確定性的 .pyc 文件
PEP 565,改進的
DeprecationWarning處理
C API 的改進:
PEP 539,用于線程本地存儲的新 C API
文檔的改進:
此版本在諸多方面有顯著的性能改進。性能優化 章節詳細列出了它們。
和之前的 Python 版本存在兼容性的更改列表,請參閱 移植到 Python 3.7 章節。
新的特性?
PEP 563:延遲的標注求值?
隨著 PEP 3107 加入標注功能并在 PEP 526 進一步細化,Python 中類型提示的出現揭示了兩個明顯的可用性問題:
標注只能使用在當前作用域中已經存在的名稱,也就是說,它們不支持任何形式的前向引用;而且——
標注源碼對 Python 程序的啟動時間有不利的影響。
這兩個問題都可以通過延遲標注求值來解決。在定義標注的時候,編譯器并不會編譯執行相應表達式的代碼,而是保存與相應表達式的 AST 等價的字符串形式。如果有需要,標注可以在運行時使用 typing.get_type_hints() 進行解析。在不需要這種解析的通常情況下,標注的存儲成本更低(因為解析器只需處理較短的字符串)且啟動時間更短。
在可用性方面,標注現在支持向前引用,以使以下句法有效:
class C:
@classmethod
def from_string(cls, source: str) -> C:
...
def validate_b(self, obj: B) -> bool:
...
class B:
...
由于此修改會破壞兼容性,在 Python 3.7 中此種新的行為需要在每個模塊層級上使用 __future__ 導入來啟用:
from __future__ import annotations
它將在 Python 3.10 中成為默認行為。
參見
- PEP 563 -- 延遲的標注求值
PEP 由 ?ukasz Langa 撰寫并實現。
PEP 538: 傳統 C 區域強制轉換?
Python 3 系列有一個持續的挑戰就是為處理 7 比特位 ASCII 文本的假定編碼確定合理的默認策略,目前的設定是在非 Windows 平臺上使用默認的 C 或 POSIX 區域設置。
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 上發出)。 此設置還會使得 Python 運行時在核心解釋器初始化時如果傳統 C 區域仍然處于激活狀態時發出警告。
雖然 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 環境變量可被用來啟用 CPython 的 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 運行時模式)。
UTF-8 模式在語言區域為 C 或 POSIX 并且 PEP 538 區域強制轉換特性無法將其修改為某種基于 UTF-8 的替代項時會被默認啟用(無論修改失敗是由于設置了 PYTHONCOERCECLOCALE=0, LC_ALL 還是由于缺少適合的目標區域)。
參見
- 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 來改變這一點,它取代了原有的 CPython 內部 TLS API 的使用,并且原有 API 已棄用。 TSS API 使用一種新類型 Py_tss_t 而非 int 來表示 TSS 密鑰 -- 這是一種不透明類型,其定義可能依賴于下層的 TLS 實現。 因此,這將允許在以無法安全地轉換為 int 的方式定義原生 TLS 密鑰的平臺上構建 CPython。
請注意在原生 TLS 密鑰定義方式無法被安全地轉換為 int 的平臺上,原有 TLS API 中的全部函數將無法執行并會立即返回失敗信息。 這樣能清楚地表明原有 API 在無法可靠使用的平臺上不受支持,并且不會再嘗試添加此類支持。
參見
- PEP 539 -- 在 CPython 中用于線程局部存儲的新 C-API
PEP 由 Erik M. Bray 撰寫;由 Masayuki Yamamoto 實現。
PEP 562: 定制對模塊屬性的訪問?
Python 3.7 允許在模塊上定義 __getattr__() 并且當以其他方式找不到某個模塊屬性時將會調用它。 在模塊上定義 __dir__() 現在也是允許的。
一個典型的可能有用的例子是已棄用模塊屬性和惰性加載。
參見
- PEP 562 -- 模塊的
__getattr__和__dir__ PEP 由 Ivan Levkivskyi 撰寫并實現
PEP 564: 具有納秒級精度的新時間函數?
現代系統的時鐘精度可以超過由 time.time() 函數及其變化形式所返回的浮點數的有限精度。 為了避免精度損失,PEP 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 PEP 由 Nick Coghlan 撰寫并實現
PEP 560: 對 typing 模塊和泛型類型的核心支持?
PEP 484 最初的設計方式使其不會向核心 CPython 解釋器引入 任何 更改。 現在類型提示和 typing 模塊已被社區廣泛使用,因此這個限制已被取消。 這個 PEP 引入了兩個特殊方法 __class_getitem__() 和 __mro_entries__,這些方法現在被 typing 中的大多數類和特殊構造所使用。 結果就是與類型相關的各類操作的速度提升了 7 倍,泛型類型可以在沒有元類沖突的情況下被使用,而 typing 模塊中幾個長期存在的錯誤也已被修正。
參見
- PEP 560 -- 對 typing 模塊和泛型類型的核心支持
PEP 由 Ivan Levkivskyi 撰寫并實現
PEP 552: 基于哈希值的 .pyc 文件?
傳統上 Python 檢查字節碼緩存文件 (即 .pyc 文件) 是否最新的方式是通過對源碼元數據 (最后更改的時間戳和大小)和生成緩存時保存在其文件頭中的源碼元數據進行比較。 這種檢查方法雖然有效,但也存在缺點。 當文件系統的時間戳太粗糙時,Python 有可能錯過源碼更新,導致用戶感到困惑。 此外,在緩存文件中存在時間戳對于 構建可再現 并且基于內容的構建系統來說是有問題的。
PEP 552 擴展了 pyc 格式以允許使用源文件的哈希值而非源文件的時間戳來檢查有效性。 這種 .pyc 文件就稱為“基于哈希值的”。 默認情況下,Python 仍然使用基于時間戳的有效性檢查,不會在運行時生成基于哈希值的 .pyc 文件。 基于哈希值的 .pyc 文件可以使用 py_compile 或 compileall 來生成。
基于哈希值的 .pyc 文件包含兩種變體:已選定和未選定。 Python 會在運行時針對相應源碼文件驗證已選定基于哈希值的 .pyc 文件,但對未選定基于哈希值的 pyc 文件則不會這樣做。 未選定基于哈希值的 .pyc 文件對于需要由 Python 外部的系統(例如構建系統)負責使 .pyc 文件保持最新的環境來說是一種有用的性能優化。
請參閱 已緩存字節碼的失效 了解更多信息。
參見
- PEP 552 -- 確定性的 pyc 文件
PEP 由 Benjamin Peterson 撰寫并實現
PEP 545: Python 文檔翻譯?
PEP 545 描述了創建和維護 Python 文檔翻譯的整個過程。
新增了三個新的翻譯版本:
參見
- PEP 545 -- Python 文檔翻譯
PEP 由 Julien Palard, Inada Naoki 和 Victor Stinner 撰寫并實現。
開發運行時模式: -X dev?
新的 -X dev 命令行選項或新的 PYTHONDEVMODE 環境變量可被用來啟用 CPython 的 開發模式。 在開發模式下,CPython 會執行額外的在默認情況下開銷過大的運行時檢查。 請參閱 -X dev 文檔查看對于此模式效果的完整描述。
其他語言特性修改?
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 d bpo-28974 中貢獻。)為更好地支持棧跟蹤的動態創建,現在
types.TracebackType可以從 Python 代碼中被實例化,并且 回溯對象 的tb_next屬性現在是可寫的。 (由 Nathaniel J. Smith 在 bpo-30579 中貢獻。)當使用
-m開關時,現在sys.path[0]會主動擴展為完整的起始目錄路徑,而不是保持為空目錄(這將允許在發生導入時從 當前 工作目錄導入) (由 Nick Coghlan 在 bpo-33053 中貢獻。)新的
-Ximporttime選項或PYTHONPROFILEIMPORTTIME環境變量可被用來顯示每次模塊導入的時間。 (由 Victor Stinner 在 bpo-31415 中貢獻。)
新增模塊?
contextvars?
新的 contextvars 模塊和一組 新的 C API 引入了對 上下文變量 的支持。 上下文變量在概念上類似于線程局部變量。 與 TLS 不同,上下文變量能正確地支持異步代碼。
asyncio 和 decimal 已得到更新以使用和支持開箱即用的上下文變量。 特別是激活的 decimal 上下文現在將存儲在上下文變量中,它允許十進制運算在異步代碼中使用正確的上下文。
參見
- PEP 567 -- 上下文變量
PEP 由 Yury Selivanov 撰寫并實現
dataclasses?
新的 dataclass() 裝飾器提供了一種聲明 數據類 的方式。 數據類使用變量標注來描述其屬性。 它的構造器和其他魔術方法例如 __repr__(), __eq__() 以及 __hash__() 會自動地生成。
示例:
@dataclass
class Point:
x: float
y: float
z: float = 0.0
p = Point(1.5, 2.5)
print(p) # produces "Point(x=1.5, y=2.5, z=0.0)"
參見
- PEP 557 -- 數據類
PEP 由 Eric V. Smith 撰寫并實現
importlib.resources?
新的 importlib.resources 模塊提供了一些新的 API 和一個新的 ABC 用于訪問、打開和讀取包內的 資源。 資源基本上類似于包內的文件,但它們不一定是物理文件系統中實際的文件。 模塊加載器可以提供 get_resource_reader() 函數,它會返回一個 importlib.abc.ResourceReader 實例來支持這個新 API。 內置的文件路徑加載器和 zip 文件加載器都支持此特性。
由 Barry Warsaw 和 Brett Cannon 在 bpo-32248 中貢獻。
參見
importlib_resources -- 用于先前 Python 版本的 PyPI 下層接口。
改進的模塊?
argparse?
新的 ArgumentParser.parse_intermixed_args() 方法允許混合選項與位置參數。 (由 paul.j3 在 bpo-14191 中提供。)
asyncio?
asyncio 模塊獲得了許多新的特性、可用性和 性能提升。 重要的改變包括:
新的 暫定
asyncio.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()方法會返回創建 task 或 future 對象的事件循環的實例。Server.get_loop()允許為asyncio.Server對象執行同樣操作。 (由 Yury Selivanov 在 bpo-32415 中,以及由 Srinivas Reddy Thatiparthy 在 bpo-32418 中貢獻。)現在可以控制
asyncio.Server的實例如何開啟服務。 之前,服務在創建后將立即開啟服務。 新的 start_serving 關鍵字參數已添加到loop.create_server()和loop.create_unix_server(),并且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()functions,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 中貢獻。)接受套接字路徑的循環方法現在支持傳入 路徑類對象。 (由 Yury Selivanov 在 bpo-32066 中貢獻。)
在
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 關鍵字參數。 當其為真值時,零會以 '`' 而非空格來表示。 (由 Xiang Zhang 在 bpo-30103 中貢獻。)
calendar?
HTMLCalendar 類具有新的類屬性,可以簡化所生成 HTML 日歷中 CSS 類的自定義。 (由 Oz Tiram 在 bpo-30095 中貢獻。)
compileall?
compileall.compile_dir() 增加了新的 invalidation_mode 形參,可用于啟用 基于哈希值的 .pyc 有效性檢測。 失效模式也可以在命令行中使用新的 --invalidation-mode 參數來指定。 (由 Benjamin Peterson 在 bpo-31650 中貢獻。)
concurrent.futures?
ProcessPoolExecutor 和 ThreadPoolExecutor 現在支持新的 初始化器 以及 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 中貢獻。)
crypt?
crypt 模塊現在支持 Blowfish 哈希方法。 (由 Serhiy Storchaka 在 bpo-31664 中貢獻。)
mksalt() 函數現在允許指定哈希操作的輪數。 (由 Serhiy Storchaka 在 bpo-31702 中貢獻。)
datetime?
新的 datetime.fromisoformat() 方法會基于由 datetime.isoformat() 所輸出的某一特定格式字符串構建 datetime 對象。 (由 Paul Ganssle 在 bpo-15873 中貢獻。)
tzinfo 類現在支持小于一分鐘的偏移量。 (由 Alexander Belopolsky 在 bpo-5288 中貢獻。)
dis?
dis() 函數現在能夠反匯編嵌套的代碼對象(推導式、生成器表達式和嵌套函數的代碼,以及用于構建嵌套類的代碼)。 反匯編遞歸的最大深度由新的 depth 形參來控制。 (由 Serhiy Storchaka 在 bpo-11822 中貢獻。)
distutils?
README.rst 現在包含在 distutils 的標準 README 列表之中,因而也包含在源碼發布之中。 (由 Ryan Gonzalez 在 bpo-11913 中貢獻。)
enum?
Enum 增加了新的 _ignore_ 類特征屬性,該屬性允許列出不應當成為枚舉成員的特征屬性名稱。 (由 Ethan Furman 在 bpo-31801 中貢獻。)
在 Python 3.8 中,嘗試在 Enum 類中檢查非 Enum 對象將引發 TypeError (例如 1 in Color);類似地,嘗試在 Flag 成員中檢查非 Flag 對象也將引發 TypeError (例如 1 in Perm.RW);目前,兩種操作均會返回 False 并且已棄用。 (由 Ethan Furman 在 bpo-33217 中貢獻。)
functools?
functools.singledispatch() 現在支持使用類型標注來注冊實現。 (由 ?ukasz Langa 在 bpo-32227 中貢獻。)
gc?
新的 gc.freeze() 函數允許凍結由垃圾回收器所跟蹤的所有對象,并將它們從未來的集合中排除。 這可以在 POSIX fork() 調用之前使用以令 GC 友好地進行寫入時復制或加速收集。 新的 gc.unfreeze() 函數會反轉此操作。 此外,gc.get_freeze_count() 可被用于獲取凍結對象的數量。 (由 Li Zekun 在 bpo-31558 中貢獻。)
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 的請求。 它會在 http.server 附帶 -m 運行時被使用。 (由 Julien Palard 在 bpo-31639 中貢獻。)
idlelib 與 IDLE?
多個對自動補全的修正。 (由 Louie Lu 在 bpo-15786 中貢獻。)
Module Browser (在 File 菜單中,之前稱為 Class Browser) 現在會在最高層級函數和類之外顯示嵌套的函數和類。 (由 Guilherme Polo, Cheryl Sabella 和 Terry Jan Reedy 在 bpo-1612262 中貢獻。)
Settings 對話框 (Options 中的 Configure IDLE) 已經被部分重寫以改進外觀和功能。 (由 Cheryl Sabella 和 Terry Jan Reedy 在多個問題項中貢獻。)
字體樣本現在包括一組非拉丁字符以便用戶能更好地查看所選特定字體的效果。 (由 Terry Jan Reedy 在 bpo-13802 中貢獻。) 樣本可以被修改以包括其他字符。 (由 Serhiy Storchaka 在 bpo-31860 中貢獻。)
之前以擴展形式實現的 IDLE 特性已作為正常特性重新實現。 它們的設置已從 Extensions 選項卡移至其他對話框選項卡。 (由 Charles Wohlganger 和 Terry Jan Reedy 在 bpo-27099 中實現。)
編輯器代碼上下文選項已經過修改。 Box 會顯示所有上下文行直到最大行數。 點擊一個上下文行會使編輯器跳轉到該行。 自定義主題的上下文顏色已添加到 Settings 對話框的 Highlights 選項卡。 (由 Cheryl Sabella 和 Terry Jan Reedy 在 bpo-33642, bpo-33768 和 bpo-33679 中貢獻。)
在 Windows 上,會有新的 API 調用將 tk 對 DPI 的調整告知 Windows。 在 Windows 8.1+ 或 10 上,如果 Python 二進制碼的 DPI 兼容屬性未改變,并且監視器分辨率大于 96 DPI,這應該會令文本和線條更清晰。 否則的話它應該不造成影響。 (由 Terry Jan Reedy 在 bpo-33656 中貢獻。)
在 3.7.1 中新增:
超過 N 行(默認值為 50)的輸出將被折疊為一個按鈕。 N 可以在 Settings 對話框的 General 頁的 PyShell 部分中進行修改。 數量較少但是超長的行可以通過在輸出上右擊來折疊。 被折疊的輸出可通過雙擊按鈕來展開,或是通過右擊按鈕來放入剪貼板或是單獨的窗口。 (由 Tal Einat 在 bpo-1529353 中貢獻。)
上述修改已被反向移植到 3.6 維護發行版中。
在 3.7.4 中新增:
在 Run 菜單中增加了 "Run Customized" 以使用自定義設置來運行模塊。 輸入的任何命令行參數都會被加入 sys.argv。 它們在下次自定義運行時會再次顯示在窗體中。 用戶也可以禁用通常的 Shell 主模塊重啟。 (由 Cheryl Sabella, Terry Jan Reedy 等人在 bpo-5680 和 bpo-37627 中貢獻。)
在 3.7.5 中新增:
在 IDLE 編輯器窗口中增加了可選的行序號。 窗口打開時默認不帶行序號,除非在配置對話框的 General 選項卡中進行設置。 已打開窗口中的行序號可以在 Options 菜單中顯示和隱藏。 (由 Tal Einat 和 Saimadhav Heblikar 在 bpo-17535 中貢獻。)
importlib?
引入了 importlib.abc.ResourceReader ABC 以支持從包中加載資源。 另請參閱 importlib.resources。 (由 Barry Warsaw, Brett Cannon 在 bpo-32248 中貢獻。)
如果模塊缺少規格描述 importlib.reload() 現在會引發 ModuleNotFoundError。 (由 Garvit Khatri 在 bpo-29851 中貢獻。)
如果指定的父模塊不是一個包 (即缺少 __path__ 屬性) importlib.find_spec() 現在會引發 ModuleNotFoundError 而非 AttributeError。 (由 Milan Oberkirch 在 bpo-30436 中貢獻。)
新的 importlib.source_hash() 可被用來計算傳入源的哈希值。 基于哈希值的 .pyc 文件 會嵌入此函數所返回的值。
io?
新的 TextIOWrapper.reconfigure() 方法可用于根據新的設置重新配置文本流。 (由 Antoine Pitrou 在 bpo-30526 以及 INADA Naoki 在 bpo-15216 中貢獻。)
ipaddress?
methods of ipaddress.IPv6Network 和 ipaddress.IPv4Network 中新的 subnet_of() 以及 supernet_of() 方法可用于網絡包含測試。 (由 Michel Albert 和 Cheryl Sabella 在 bpo-20825 中貢獻。)
itertools?
itertools.islice() 現在接受 類整數對象 作為 start, stop 和 slice 參數。 (由 Will Roberts 在 bpo-30537 中貢獻。)
locale?
locale.format_string() 中新的 monetary 參數可用于轉換所使用的千位分隔符和分組字符串。 (由 Garvit 在 bpo-10379 中貢獻。)
現在 locale.getpreferredencoding() 函數在 Android 上或是在 強制 UTF-8 模式 下總是返回 'UTF-8' 。
logging?
Logger 實例現在可以被 pickle。 (由 Vinay Sajip 在 bpo-30520 中貢獻。)
新的 StreamHandler.setStream() 方法可用于在句柄創建之后替換日志流。 (由 Vinay Sajip 在 bpo-30522 中創建。)
現在可以在傳遞給 logging.config.fileConfig() 的配置信息中對句柄構造器指定關鍵字參數。 (由 Preston Landers 在 bpo-31080 中貢獻。)
math?
新的 math.remainder() 函數實現了 IEEE 754 風格的余數運算。 (由 Mark Dickinson 在 bpo-29962 中貢獻。)
msilib?
新的 Database.Close() 方法可用于關閉 MSI 數據庫。 (由 Berker Peksag 在 bpo-20486 中貢獻。)
multiprocessing?
新的 Process.close() 方法會顯式地關閉進程對象并釋放與其關聯的所有資源。 如果底層進程仍在運行則將引發 ValueError。 (由 Antoine Pitrou 在 bpo-30596 中貢獻。)
新的 Process.kill() 方法可用于在 Unix 上使用 SIGKILL 信號來終止進程。 (由 Vitor Pereira 在 bpo-30794 中貢獻。)
由 Process 所創建的非守護線程現在會在進程退出時被合并。 (由 Antoine Pitrou 在 bpo-18966 中貢獻。)
os?
os.fwalk() 現在接受 bytes 類型的 path 參數。 (由 Serhiy Storchaka 在 bpo-28682 中貢獻。)
os.scandir() 已獲得對 文件描述器 的支持。 (由 Serhiy Storchaka 在 bpo-25996 中貢獻。)
新的 register_at_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 中貢獻。)
在 Solaris 及其派生系統上 os.stat() 所返回的結構現在會包含 st_fstype 屬性。 (由 Jesús Cea Avión 在 bpo-32659 中貢獻。)
pathlib?
在 POSIX 類系統上新的 Path.is_mount() 方法現在可用于確定一個路徑是否為掛載點。 (由 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 中貢獻。)
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 參數現在接受任何 path-like object,而不是只接受字符串。 (由 Anders Lorentsen 在 bpo-31843 中貢獻。)
ssl?
ssl 模塊現在使用 OpenSSL 的內置 API 代替 match_hostname() 來檢查主機名或 IP 地址。 值的驗證會在 TLS 握手期間進行。 任何證書驗證錯誤包括主機名檢查失敗現在將引發 SSLCertVerificationError 并使用正確的 TLS Alert 消息中止握手過程。 這個新異常包含有額外的信息。 主機名驗證可通過 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 中貢獻。)
用于設置最小和最大 TLS 協議版本的 OpenSSL 1.1 API 現已可用,名稱分別為 SSLContext.minimum_version 和 SSLContext.maximum_version。 受支持的協議由幾個新增旗標指定,例如 HAS_TLSv1_1。 (由 Christian Heimes 在 bpo-32609 中貢獻。)
增加了 SSLContext.post_handshake_auth 以及 ssl.SSLSocket.verify_client_post_handshake() 來啟用并初始化 TLS 1.3 握手后驗證。 (由 Christian Heimes 在 bpo-34670 中貢獻。)
string?
string.Template 現在允許你有選擇地分別修改帶大括號的占位符和不帶大括號的占位符所對應的正則表達式模式。 (由 Barry Warsaw 在 bpo-1198569 中貢獻。)
subprocess?
subprocess.run() 函數接受新的 capture_output 關鍵字參數。 當其為真值時,將會捕獲 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 設為真值。 參閱 subprocess.Popen。 這意味著現在 close_fds 在所有受支持的平臺上默認值均為 True。 (由 Segev Finer 在 bpo-19764 中貢獻。)
在 subprocess.call(), subprocess.run() 期間或在 Popen 上下文管理器中,subprocess 模塊現在能更優雅地處理 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 關鍵字參數。 當其為真時,零會以 '`' 而非空格來表示。 (由 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 專屬的-Xdev選項)啟用的警告總是會通過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 在 bpo-17239 中貢獻。)
xml.etree?
find() 方法中的 ElementPath 描述詞現在可以將當前節點文本與 [. = "text"] 進行比較,而不僅是子節點中的文本。 描述詞還允許添加空格以提高可讀性。 (由 Stefan Behnel 在 bpo-31648 中貢獻。)
zipapp?
函數 create_archive() 現在接受可選的 filter 參數,以允許用戶選擇哪些文件應被加入歸檔包。 (由 Irmen de Jong 在 bpo-31072 中貢獻。)
函數 create_archive() 現在接受可選的 compressed 參數,以生成壓縮歸檔包。 另外也加入了命令行選項 --compress 以支持壓縮。 (由 Zhiming Wang 在 bpo-31638 中貢獻。)
C API 的改變?
已實現了用于線程本地存儲的新 API。 相關概述請參閱 PEP 539: 用于線程局部存儲的新 C API,完整參考文檔請查看 Thread Specific Storage (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() 已棄用,建議改用新的 functions PyOS_BeforeFork(), PyOS_AfterFork_Parent() 和 PyOS_AfterFork_Child()。 (由 Antoine Pitrou 在 bpo-16500 中貢獻。)
曾經作為公共 API 一部分的 PyExc_RecursionErrorInst 單例已被移除,因為它的成員永遠不會被清理,可能在解釋器的最終化過程中導致段錯誤。 由 Xavier de Gaye 在 bpo-22898 和 bpo-30697 中貢獻。
添加 C API 對使用 timezone 的構造器 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 中貢獻。)
現在 PyUnicode_AsWideCharString() 如果第二個參數為 NULL 并且 wchar_t* 字符串包含空字符則會引發 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 中貢獻。)
通過各種優化方式,使 Python 在 Linux 上的啟動時間縮短了 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 在 bpo-28638 中貢獻,進一步的改進由 INADA Naoki, Serhiy Storchaka 和 Raymond Hettinger 貢獻。)
現在 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 中貢獻。)
re.compile() 現在會將 flags 形參轉換為 int 對象,如果它是 RegexFlag 的話。 它現在會和 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而是選擇從解釋器接收opcode事件,具體做法是在被跟蹤的幀上相應地設置新的f_trace_lines和f_trace_opcodes屬性。 (由 Nick Coghlan 在 bpo-31344 中貢獻。)修復了一些命名空間包模塊屬性的一致性問題。 命名空間模塊對象的
__file__被設置為None(原先未設置),對象的__spec__.origin也被設置為None(之前為字符串"namespace")。 參見 bpo-32305。 而且,命名空間模塊對象的__spec__.loader被設置的值與__loader__相同 (原先前者被設置為None)。 參見 bpo-32303。locals()字典現在以變量定義的詞法順序顯示。 原先未定義順序。 (由 Raymond Hettinger 在 bpo-32690 中貢獻。)distutilsupload命令不會再試圖將行結束字符 CR 改為 CRLF。 這修復了 sdists 的一個以與 CR 等價的字節結束的數據損壞問題。 (由 Bo Bayles 在 bpo-32304 中貢獻。)
已棄用的 Python 行為?
在推導式和生成器表達式中的 yield 語句(包括 yield 和 yield from 子句)現在已棄用(最左端的 for 子句中的可迭代對象表達式除外)。 這確保了推導式總是立即返回適當類型的容器(而不是有可能返回 generator iterator 對象),這樣生成器表達式不會試圖將它們的隱式輸出與任何來自顯式 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?
對 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 內的抽象基類將不會再通過常規的 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 中貢獻。)
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 中貢獻。)
threading?
dummy_threading 和 _dummy_thread 已棄用。 構建禁用線程的 Python 已不再可能。 請改用 threading。 (由 Antoine Pitrou 在 bpo-31370 中貢獻。)
socket?
socket.htons() 和 socket.ntohs() 中的靜默參數截斷已棄用。 在未來的 Python 版本中,如果傳入的參數長度大于 16 比特位,將會引發異常。 (由 Oren Milman 在 bpo-28332 中貢獻。)
ssl?
ssl.wrap_socket() 已棄用。 請改用 ssl.SSLContext.wrap_socket()。 (由 Christian Heimes 在 bpo-28124 中貢獻。)
sunau?
sunau.openfp() 已棄用并將在 Python 3.9 中被移除。 請改用 sunau.open()。 (由 Brian Curtin 在 bpo-31985 中貢獻。)
sys?
已棄用 sys.set_coroutine_wrapper() 和 sys.get_coroutine_wrapper()。
未寫入文檔的 sys.callstats() 函數已棄用并將在未來的 Python 版本中被移除。 (由 Victor Stinner 在 bpo-28799 中貢獻。)
wave?
wave.openfp() 已棄用并將在 Python 3.9 中被移除。 請改用 wave.open()。 (由 Brian Curtin 在 bpo-31985 中貢獻。)
已棄用的 C API 函數和類型?
如果 Py_LIMITED_API 未設定或設定為范圍在 0x03050400 和 0x03060000 (不含) 之間,或為 0x03060100 或更高的值,函數 PySlice_GetIndicesEx() 已棄用并被一個宏所替代。 (由 Serhiy Storchaka 在 bpo-27867 中貢獻。)
PyOS_AfterFork() 已棄用。 請改用 PyOS_BeforeFork(), PyOS_AfterFork_Parent() 或 PyOS_AfterFork_Child()。 (由 Antoine Pitrou 在 bpo-16500 中貢獻。)
平臺支持的移除?
官方已不再支持 FreeBSD 9 及更舊的版本。
為了完整的 Unicode 支持,包括在擴展模塊之內,*nix 平臺現在至少應當提供
C.UTF-8(完整區域),C.utf8(完整區域) 或UTF-8(LC_CTYPE專屬區域) 中的一個作為基于ASCII的傳統C區域的替代。OpenSSL 0.9.8 和 1.0.1 已不再受支持,這意味著在仍然使用這些版本的舊平臺上構建帶有 SSL/TLS 支持的 CPython 3.7 時,需要自定義構建選項以鏈接到更新的 OpenSSL 版本。
注意,此問題會影響到 Debian 8 (代號“jessie”) 和 Ubuntu 14.04 (代號“Trusty”) 等長期支持 Linux 發行版,因為它們默認仍然使用 OpenSSL 1.0.1。
Debian 9 (“stretch”) 和 Ubuntu 16.04 (“xenial”) 以及其他最新的長期支持 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 在 bpo-28638 中貢獻,進一步的改進由 INADA Naoki, Serhiy Storchaka 和 Raymond Hettinger 貢獻。)函數
bool(),float(),list()和tuple()不再接受關鍵字參數。int()的第一個參數現在只能作為位置參數傳入。移除了之前在 Python 2.4 中已棄用的
plistlib模塊的類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 中貢獻。)未被使用的
distutilsinstall_misc命令已被移除。 (由 Eric N. Vander Weele 在 bpo-29218 中貢獻。)
移除的模塊?
fpectl 模塊已被移除。 它從未被默認啟用,從未在 x86-64 上正確發揮效果,并且它對 Python ABI 的改變會導致 C 擴展的意外損壞。 (由 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 中貢獻。)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。 如果你以前依賴于在使用帶有標準 io 重定向的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 在一系列其他問題報告中進一步更新)。 已知會受到影響的一些細節:
PySys_AddWarnOptionUnicode()目前對嵌入式應用程序不可用,因為在調用 Py_Initialize 之前需要創建 Unicode 對象。 請改用PySys_AddWarnOption()。嵌入式應用程序通過
PySys_AddWarnOption()所添加的警告過濾器現在應該以更高的一致性優先于由解釋器所設置的默認過濾器
由于默認警告過濾器的配置方式發生了變化,將 Py_BytesWarningFlag 設置為大于一的值不再足以在發出 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。
在默認情況下 xml.dom.minidom 和 xml.sax 模塊將不再處理外部實體。 另請參閱 bpo-17239。
在 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() 中 query 形參的分隔鍵。 出于安全考慮,也為了遵循更新的 W3C 推薦設置,這已被改為只允許單個分隔鍵,默認為 &。 這一改變還會影響 cgi.parse() 和 cgi.parse_multipart() 因為它們在內部使用了受影響的函數。 要了解更多細節,請查看它們各自的文檔。 (由 Adam Goldschmidt, Senthil Kumaran 和 Ken Jin 在 bpo-42967 中貢獻。)
Notable changes in Python 3.7.11?
新的安全修正將A security fix alters the ftplib.FTP 的行為改成當設置被動數據通道時不信任遠程服務器所發送的 IPv4 地址。 我們會改為重用 FTP 服務器的 IP 地址。 對于需要原先行為的不常見代碼,請在你的 FTP 實例上設置 trust_server_pasv_ipv4_address 屬性為 True。 (參見 bpo-43285)
The presence of newline or tab characters in parts of a URL allows for some
forms of attacks. Following the WHATWG specification that updates RFC 3986,
ASCII newline \n, \r and tab \t characters are stripped from the
URL by the parser urllib.parse() preventing such attacks. The removal
characters are controlled by a new module level variable
urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE. (See bpo-43882)
