Python 3.6 中的新增功能¶
- 編輯:
Elvis Pranskevichus <elvis@magic.io>, Yury Selivanov <yury@magic.io>
本文解釋了 Python 3.6 相較於 3.5 的新功能。Python 3.6 於 2016 年 12 月 23 日釋出。有關完整的更改列表,請參閱 更新日誌。
參見
PEP 494 - Python 3.6 釋出時間表
摘要 – 釋出亮點¶
新語法功能
新庫模組
CPython 實現改進
dict 型別已重新實現,以使用基於 Raymond Hettinger 的提案 的“更緊湊表示”,類似於 PyPy dict 實現。這使得字典比 Python 3.5 減少了 20% 到 25% 的記憶體使用。
使用 新協議 簡化了類建立的自定義。
類屬性的定義順序 現在得到保留。
**kwargs中元素的順序現在 對應於 關鍵字引數傳遞給函式的順序。已新增 DTrace 和 SystemTap 探測支援。
新的 PYTHONMALLOC 環境變數現在可用於除錯直譯器記憶體分配和訪問錯誤。
標準庫的重大改進
asyncio模組獲得了新功能、顯著的可用性和效能改進,以及大量的 bug 修復。從 Python 3.6 開始,asyncio模組不再是臨時性的,其 API 被認為是穩定的。tracemalloc模組已進行了重大修改,現在用於為ResourceWarning提供更好的輸出,併為記憶體分配錯誤提供更好的診斷。有關更多資訊,請參閱 PYTHONMALLOC 部分。
安全改進
已新增新的
secrets模組,以簡化加密強度偽隨機數的生成,適用於管理賬戶認證、令牌等金鑰。在 Linux 上,
os.urandom()現在會阻塞,直到系統 urandom 熵池初始化,以提高安全性。有關理由,請參閱 PEP 524。ssl模組的預設設定和功能集已得到改進。hashlib模組獲得了對 BLAKE2、SHA-3 和 SHAKE 雜湊演算法以及scrypt()金鑰派生函式的支援。
Windows 改進
py.exe啟動器在互動式使用時,當用戶未指定版本(透過命令列引數或配置檔案)時,不再優先選擇 Python 2 而不是 Python 3。shebang 行的處理保持不變 - 在這種情況下,“python”指的是 Python 2。python.exe和pythonw.exe已被標記為支援長路徑,這意味著 260 字元的路徑限制可能不再適用。有關詳細資訊,請參閱 刪除 MAX_PATH 限制。可以新增
._pth檔案以強制隔離模式並完全指定所有搜尋路徑,以避免登錄檔和環境查詢。有關更多資訊,請參閱 文件。python36.zip檔案現在可用作推斷PYTHONHOME的標誌。有關更多資訊,請參閱 文件。
新功能¶
PEP 498: 格式化字串字面量¶
PEP 498 引入了一種新型字串字面量:f-strings,或 格式化字串字面量。
格式化字串字面量以 'f' 為字首,類似於 str.format() 接受的格式字串。它們包含由花括號包圍的替換欄位。替換欄位是表示式,在執行時求值,然後使用 format() 協議進行格式化
>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # nested fields
'result: 12.35'
PEP 526: 變數註釋語法¶
PEP 484 引入了函式引數型別註釋(即型別提示)的標準。本 PEP 為 Python 添加了用於註釋變數(包括類變數和例項變數)型別的語法
primes: List[int] = []
captain: str # Note: no initial value!
class Starship:
stats: Dict[str, int] = {}
與函式註釋一樣,Python 直譯器不會為變數註釋附加任何特定含義,而只是將它們儲存在類或模組的 __annotations__ 屬性中。
與靜態型別語言中的變數宣告相反,註釋語法的目標是提供一種簡單的方式,透過抽象語法樹和 __annotations__ 屬性為第三方工具和庫指定結構化型別元資料。
PEP 515: 數字字面量中的下劃線¶
PEP 515 增加了在數字字面量中使用下劃線以提高可讀性的能力。例如
>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295
允許在數字之間和任何基數說明符之後使用單個下劃線。不允許前導、尾隨或連續多個下劃線。
字串格式化 語言現在也支援 '_' 選項,用於指示浮點表示型別和整數表示型別 'd' 使用下劃線作為千位分隔符。對於整數表示型別 'b'、'o'、'x' 和 'X',每 4 位插入下劃線
>>> '{:_}'.format(1000000)
'1_000_000'
>>> '{:_x}'.format(0xFFFFFFFF)
'ffff_ffff'
參見
- PEP 515 – 數字字面量中的下劃線
PEP 由 Georg Brandl 和 Serhiy Storchaka 編寫。
PEP 525: 非同步生成器¶
PEP 492 在 Python 3.5 中引入了對原生協程和 async / await 語法的支援。Python 3.5 實現的一個顯著限制是無法在同一函式體中使用 await 和 yield。在 Python 3.6 中,此限制已解除,使得定義 非同步生成器 成為可能
async def ticker(delay, to):
"""Yield numbers from 0 to *to* every *delay* seconds."""
for i in range(to):
yield i
await asyncio.sleep(delay)
新語法允許更快、更簡潔的程式碼。
參見
- PEP 525 – 非同步生成器
PEP 由 Yury Selivanov 編寫和實現。
PEP 530: 非同步推導式¶
PEP 530 增加了在列表、集合、字典推導式和生成器表示式中使用 async for 的支援
result = [i async for i in aiter() if i % 2]
此外,所有型別的推導式都支援 await 表示式
result = [await fun() for fun in funcs if await condition()]
參見
- PEP 530 – 非同步推導式
PEP 由 Yury Selivanov 編寫和實現。
PEP 487: 更簡單的類建立自定義¶
現在可以在不使用元類的情況下自定義子類建立。每當建立新子類時,都會在基類上呼叫新的 __init_subclass__ 類方法
class PluginBase:
subclasses = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.subclasses.append(cls)
class Plugin1(PluginBase):
pass
class Plugin2(PluginBase):
pass
為了使無引數的 super() 呼叫能夠從 __init_subclass__() 實現中正確工作,自定義元類必須確保新的 __classcell__ 名稱空間條目傳播到 type.__new__(如 建立類物件 中所述)。
PEP 487: 描述符協議增強¶
PEP 487 擴充套件了描述符協議,包括新的可選 __set_name__() 方法。每當定義一個新類時,將在定義中包含的所有描述符上呼叫新方法,向它們提供對正在定義的類及其在類名稱空間中賦予描述符的名稱的引用。換句話說,描述符的例項現在可以知道所有者類中描述符的屬性名稱
class IntField:
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not isinstance(value, int):
raise ValueError(f'expecting integer in {self.name}')
instance.__dict__[self.name] = value
# this is the new initializer:
def __set_name__(self, owner, name):
self.name = name
class Model:
int_field = IntField()
PEP 519: 新增檔案系統路徑協議¶
檔案系統路徑歷來以 str 或 bytes 物件表示。這導致編寫操作檔案系統路徑的程式碼的人假設此類物件只有這兩種型別之一(表示檔案描述符的 int 不算作檔案路徑)。不幸的是,這種假設阻止了檔案系統路徑的其他物件表示(如 pathlib)與現有程式碼(包括 Python 的標準庫)一起工作。
為了解決這種情況,定義了一個由 os.PathLike 表示的新介面。透過實現 __fspath__() 方法,物件表示它是一個路徑。然後,物件可以提供檔案系統路徑的低階表示,作為 str 或 bytes 物件。這意味著如果物件實現 os.PathLike 或者是一個表示檔案系統路徑的 str 或 bytes 物件,則認為該物件是 類路徑物件。程式碼可以使用 os.fspath()、os.fsdecode() 或 os.fsencode() 顯式獲取類路徑物件的 str 和/或 bytes 表示。
內建函式 open() 已更新,以接受 os.PathLike 物件,os 和 os.path 模組中的所有相關函式以及標準庫中的大多數其他函式和類也已更新。 os.DirEntry 類和 pathlib 中的相關類也已更新以實現 os.PathLike。
希望更新操作檔案系統路徑的基本函式將導致第三方程式碼隱式支援所有 類路徑物件,而無需任何程式碼更改,或至少只需要極少的更改(例如,在操作類路徑物件之前在程式碼開頭呼叫 os.fspath())。
以下是一些新介面如何使 pathlib.Path 更容易、更透明地與現有程式碼一起使用的示例
>>> import pathlib
>>> with open(pathlib.Path("README")) as f:
... contents = f.read()
...
>>> import os.path
>>> os.path.splitext(pathlib.Path("some_file.txt"))
('some_file', '.txt')
>>> os.path.join("/a/b", pathlib.Path("c"))
'/a/b/c'
>>> import os
>>> os.fspath(pathlib.Path("some_file.txt"))
'some_file.txt'
(由 Brett Cannon、Ethan Furman、Dusty Phillips 和 Jelle Zijlstra 貢獻。)
參見
- PEP 519 – 新增檔案系統路徑協議
PEP 由 Brett Cannon 和 Koos Zevenhoven 編寫。
PEP 495: 本地時間消歧¶
在世界上大多數地方,曾發生過並且將發生本地時鐘回撥的情況。在這些時候,會引入一些時間間隔,其中本地時鐘在同一天兩次顯示相同的時間。在這些情況下,本地時鐘顯示的資訊(或儲存在 Python datetime 例項中)不足以識別特定時間點。
PEP 495 為 datetime.datetime 和 datetime.time 類的例項添加了新的 fold 屬性,以區分在本地時間相同的情況下兩個時間點
>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> for i in range(4):
... u = u0 + i*HOUR
... t = u.astimezone(Eastern)
... print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0
除了表示歧義情況下的第二個(按時間順序)時間點的例項外,fold 屬性的值對於所有例項都為 0。
參見
- PEP 495 – 本地時間消歧
PEP 由 Alexander Belopolsky 和 Tim Peters 編寫,由 Alexander Belopolsky 實現。
PEP 529: 將 Windows 檔案系統編碼更改為 UTF-8¶
表示檔案系統路徑最好使用 str (Unicode) 而不是 bytes。但是,在某些情況下,使用 bytes 是足夠且正確的。
在 Python 3.6 之前,在 Windows 上使用 bytes 路徑可能會導致資料丟失。透過此更改,現在在 Windows 上支援使用 bytes 表示路徑,前提是這些 bytes 使用 sys.getfilesystemencoding() 返回的編碼進行編碼,該編碼現在預設為 'utf-8'。
不使用 str 表示路徑的應用程式應使用 os.fsencode() 和 os.fsdecode() 來確保其 bytes 已正確編碼。要恢復到以前的行為,請設定 PYTHONLEGACYWINDOWSFSENCODING 或呼叫 sys._enablelegacywindowsfsencoding()。
有關更多資訊和可能需要的程式碼修改的討論,請參閱 PEP 529。
PEP 528: 將 Windows 控制檯編碼更改為 UTF-8¶
Windows 上的預設控制檯現在將接受所有 Unicode 字元,並向 Python 程式碼提供正確讀取的 str 物件。sys.stdin、sys.stdout 和 sys.stderr 現在預設為 utf-8 編碼。
此更改僅適用於互動式控制檯,而不適用於重定向檔案或管道。要恢復互動式控制檯使用的以前行為,請設定 PYTHONLEGACYWINDOWSSTDIO。
參見
- PEP 528 – 將 Windows 控制檯編碼更改為 UTF-8
PEP 由 Steve Dower 編寫和實現。
PEP 520: 保留類屬性定義順序¶
類定義體中的屬性具有自然順序:名稱在原始碼中出現的相同順序。此順序現在保留在新類的 __dict__ 屬性中。
此外,有效的預設類 執行 名稱空間(從 type.__prepare__() 返回)現在是一個保持插入順序的對映。
參見
- PEP 520 – 保留類屬性定義順序
PEP 由 Eric Snow 編寫和實現。
PEP 468: 保留關鍵字引數順序¶
函式簽名中的 **kwargs 現在保證是保持插入順序的對映。
參見
- PEP 468 – 保留關鍵字引數順序
PEP 由 Eric Snow 編寫和實現。
新的 dict 實現¶
dict 型別現在使用基於 Raymond Hettinger 提案 的“緊湊”表示,該提案 最初由 PyPy 實現。與 Python 3.5 相比,新的 dict() 的記憶體使用量減少了 20% 到 25%。
此新實現的保持順序方面被認為是實現細節,不應依賴(未來可能會改變,但希望此新 dict 實現能在語言中存在幾個版本,然後才更改語言規範以強制所有當前和未來 Python 實現的保持順序語義;這也有助於保持與舊語言版本(其中隨機迭代順序仍然有效,例如 Python 3.5)的向後相容性)。
(由 INADA Naoki 在 bpo-27350 中貢獻。想法 最初由 Raymond Hettinger 提出。)
PEP 523: 向 CPython 新增幀評估 API¶
雖然 Python 提供了廣泛的支援來定製程式碼的執行方式,但它在幀物件的評估方面卻沒有這樣做。如果您想要某種方式來攔截 Python 中的幀評估,那麼除了直接操作已定義函式的函式指標之外,實際上沒有任何辦法。
PEP 523 透過提供一個 API 來在 C 級別上使幀評估可插拔,從而改變了這一點。這將允許偵錯程式和 JIT 等工具在 Python 程式碼執行開始之前攔截幀評估。這使得可以使用替代的 Python 程式碼評估實現、跟蹤幀評估等。
此 API 不屬於受限 C API,並被標記為私有,以表明此 API 的使用預計將受到限制,並且僅適用於非常特定的低階用例。API 的語義將根據需要隨 Python 更改。
參見
- PEP 523 – 向 CPython 新增幀評估 API
PEP 由 Brett Cannon 和 Dino Viehland 編寫。
PYTHONMALLOC 環境變數¶
新的 PYTHONMALLOC 環境變數允許設定 Python 記憶體分配器並安裝除錯鉤子。
現在可以使用 PYTHONMALLOC=debug 在以釋出模式編譯的 Python 上安裝 Python 記憶體分配器上的除錯鉤子。除錯鉤子的效果
新分配的記憶體用位元組
0xCB填充釋放的記憶體用位元組
0xDB填充檢測違反 Python 記憶體分配器 API 的情況。例如,在由
PyMem_Malloc()分配的記憶體塊上呼叫PyObject_Free()。檢測緩衝區開始之前的寫入(緩衝區下溢)
檢測緩衝區結束之後的寫入(緩衝區溢位)
檢查在呼叫
PYMEM_DOMAIN_OBJ(例如:PyObject_Malloc())和PYMEM_DOMAIN_MEM(例如:PyMem_Malloc())域的分配器函式時是否持有 GIL。
檢查是否持有 GIL 也是 Python 3.6 的一個新功能。
有關 Python 記憶體分配器上的除錯鉤子,請參閱 PyMem_SetupDebugHooks() 函式。
現在還可以使用 PYTHONMALLOC=malloc 強制所有 Python 記憶體分配使用 C 庫的 malloc() 分配器。這在使用 Valgrind 等外部記憶體偵錯程式對以釋出模式編譯的 Python 進行除錯時很有幫助。
出現錯誤時,Python 記憶體分配器上的除錯鉤子現在使用 tracemalloc 模組獲取分配記憶體塊的回溯。
使用 python3.6 -X tracemalloc=5(在跟蹤中儲存 5 個幀)時緩衝區溢位的致命錯誤示例
Debug memory block at address p=0x7fbcd41666f8: API 'o'
4 bytes originally requested
The 7 pad bytes at p-7 are FORBIDDENBYTE, as expected.
The 8 pad bytes at tail=0x7fbcd41666fc are not all FORBIDDENBYTE (0xfb):
at tail+0: 0x02 *** OUCH
at tail+1: 0xfb
at tail+2: 0xfb
at tail+3: 0xfb
at tail+4: 0xfb
at tail+5: 0xfb
at tail+6: 0xfb
at tail+7: 0xfb
The block was made by call #1233329 to debug malloc/realloc.
Data at p: 1a 2b 30 00
Memory block allocated at (most recent call first):
File "test/test_bytes.py", line 323
File "unittest/case.py", line 600
File "unittest/case.py", line 648
File "unittest/suite.py", line 122
File "unittest/suite.py", line 84
Fatal Python error: bad trailing pad byte
Current thread 0x00007fbcdbd32700 (most recent call first):
File "test/test_bytes.py", line 323 in test_hex
File "unittest/case.py", line 600 in run
File "unittest/case.py", line 648 in __call__
File "unittest/suite.py", line 122 in run
File "unittest/suite.py", line 84 in __call__
File "unittest/suite.py", line 122 in run
File "unittest/suite.py", line 84 in __call__
...
DTrace 和 SystemTap 探測支援¶
Python 現在可以構建 --with-dtrace,這會為直譯器中的以下事件啟用靜態標記
函式呼叫/返回
垃圾回收開始/結束
執行的程式碼行。
這可用於在生產中檢測正在執行的直譯器,而無需重新編譯特定的 除錯版本 或提供應用程式特定的效能分析/除錯程式碼。
更多詳細資訊請參見 使用 DTrace 和 SystemTap 檢測 CPython。
當前的實現已在 Linux 和 macOS 上測試。未來可能會新增更多標記。
(由 Łukasz Langa 在 bpo-21590 中貢獻,基於 Jesús Cea Avión、David Malcolm 和 Nikhil Benesch 的補丁。)
其他語言更改¶
對核心 Python 語言做了一些較小的更改
global或nonlocal語句現在必須在同一作用域內受影響名稱的第一次使用之前文字性地出現。以前這是一個SyntaxWarning。現在可以將 特殊方法 設定為
None,以指示相應的操作不可用。例如,如果一個類將__iter__()設定為None,則該類不可迭代。(由 Andrew Barnert 和 Ivan Levkivskyi 在 bpo-25958 中貢獻。)長序列的重複回溯行現在縮寫為
"[Previous line repeated {count} more times]"(參見 回溯 以獲得示例)。(由 Emanuel Barry 在 bpo-26823 中貢獻。)當無法找到模組時,import 現在會引發新的異常
ModuleNotFoundError(ImportError的子類)。目前檢查 ImportError(在 try-except 中)的程式碼仍然有效。(由 Eric Snow 在 bpo-15767 中貢獻。)依賴於無引數
super()的類方法現在在類建立期間從元類方法呼叫時將正確工作。(由 Martin Teichmann 在 bpo-23722 中貢獻。)
新模組¶
secrets¶
新的 secrets 模組的主要目的是提供一種顯而易見的方法,可靠地生成加密強度偽隨機值,適用於管理帳戶認證、令牌等金鑰。
警告
請注意,random 模組中的偽隨機生成器 不應 用於安全目的。在 Python 3.6 及更高版本上使用 secrets,在 Python 3.5 及更早版本上使用 os.urandom()。
參見
- PEP 506 – 向標準庫新增 Secrets 模組
PEP 由 Steven D’Aprano 編寫和實現。
改進的模組¶
array¶
array.array 的耗盡迭代器現在即使迭代的陣列被擴充套件,也將保持耗盡狀態。這與其他可變序列的行為一致。
由 Serhiy Storchaka 在 bpo-26492 中貢獻。
ast¶
已新增新的 ast.Constant AST 節點。外部 AST 最佳化器可以使用它進行常量摺疊。
由 Victor Stinner 在 bpo-26146 中貢獻。
asyncio¶
從 Python 3.6 開始,asyncio 模組不再是臨時性的,其 API 被認為是穩定的。
自 Python 3.5.0 以來 asyncio 模組的顯著更改(由於臨時狀態,所有更改都已回溯到 3.5.x)
get_event_loop()函式已更改為從協程和回撥呼叫時始終返回當前執行的迴圈。(由 Yury Selivanov 在 bpo-28613 中貢獻。)ensure_future()函式以及所有使用它的函式,例如loop.run_until_complete(),現在接受所有型別的 可等待物件。(由 Yury Selivanov 貢獻。)新的
run_coroutine_threadsafe()函式用於從其他執行緒向事件迴圈提交協程。(由 Vincent Michel 貢獻。)新的
Transport.is_closing()方法用於檢查傳輸是否正在關閉或已關閉。(由 Yury Selivanov 貢獻。)loop.create_server()方法現在可以接受主機列表。(由 Yann Sionneau 貢獻。)新的
loop.create_future()方法用於建立 Future 物件。這允許替代事件迴圈實現(例如 uvloop)提供更快的asyncio.Future實現。(由 Yury Selivanov 在 bpo-27041 中貢獻。)新的
loop.get_exception_handler()方法用於獲取當前的異常處理程式。(由 Yury Selivanov 在 bpo-27040 中貢獻。)新的
StreamReader.readuntil()方法用於從流中讀取資料,直到出現分隔符位元組序列。(由 Mark Korenberg 貢獻。)StreamReader.readexactly()的效能已得到改進。(由 Mark Korenberg 在 bpo-28370 中貢獻。)loop.getaddrinfo()方法已最佳化,如果地址已解析,則避免呼叫系統getaddrinfo函式。(由 A. Jesse Jiryu Davis 貢獻。)loop.stop()方法已更改為在當前迭代後立即停止迴圈。作為上次迭代結果的任何新排程回撥都將被丟棄。(由 Guido van Rossum 在 bpo-25593 中貢獻。)Future.set_exception現在在傳遞StopIteration異常的例項時將引發TypeError。(由 Chris Angelico 在 bpo-26221 中貢獻。)新的
loop.connect_accepted_socket()方法供在 asyncio 之外接受連線但使用 asyncio 處理它們的伺服器使用。(由 Jim Fulton 在 bpo-27392 中貢獻。)預設情況下,所有 TCP 傳輸現在都設定了
TCP_NODELAY標誌。(由 Yury Selivanov 在 bpo-27456 中貢獻。)新的
loop.shutdown_asyncgens()用於在關閉迴圈之前正確關閉待處理的非同步生成器。(由 Yury Selivanov 在 bpo-28003 中貢獻。)Future和Task類現在具有最佳化的 C 實現,這使得 asyncio 程式碼速度提高了 30%。(由 Yury Selivanov 和 INADA Naoki 在 bpo-26081 和 bpo-28544 中貢獻。)
binascii¶
b2a_base64() 函式現在接受可選的 newline 關鍵字引數,以控制是否將換行符附加到返回值。(由 Victor Stinner 在 bpo-25357 中貢獻。)
cmath¶
已新增新的 cmath.tau (τ) 常量。(由 Lisa Roach 在 bpo-12345 中貢獻,有關詳細資訊請參見 PEP 628。)
新常量:cmath.inf 和 cmath.nan 以匹配 math.inf 和 math.nan,以及 cmath.infj 和 cmath.nanj 以匹配複雜 repr 使用的格式。(由 Mark Dickinson 在 bpo-23229 中貢獻。)
collections¶
已新增新的 Collection 抽象基類,用於表示有大小的可迭代容器類。(由 Ivan Levkivskyi 貢獻,文件由 Neil Girdhar 在 bpo-27598 中編寫。)
新的 Reversible 抽象基類表示也提供 __reversed__() 方法的可迭代類。(由 Ivan Levkivskyi 在 bpo-25987 中貢獻。)
新的 AsyncGenerator 抽象基類表示非同步生成器。(由 Yury Selivanov 在 bpo-28720 中貢獻。)
namedtuple() 函式現在接受可選的關鍵字引數 module,當指定時,它將用於返回的命名元組類的 __module__ 屬性。(由 Raymond Hettinger 在 bpo-17941 中貢獻。)
namedtuple() 的 verbose 和 rename 引數現在僅限關鍵字。(由 Raymond Hettinger 在 bpo-25628 中貢獻。)
遞迴的 collections.deque 例項現在可以被 pickle。(由 Serhiy Storchaka 在 bpo-26482 中貢獻。)
concurrent.futures¶
ThreadPoolExecutor 類建構函式現在接受可選的 thread_name_prefix 引數,以便可以自定義由池建立的執行緒的名稱。(由 Gregory P. Smith 在 bpo-27664 中貢獻。)
contextlib¶
已新增 contextlib.AbstractContextManager 類,用於為上下文管理器提供抽象基類。它為 __enter__() 提供了合理的預設實現,該實現返回 self 並將 __exit__() 留作抽象方法。已向 typing 模組添加了一個匹配的類作為 typing.ContextManager。(由 Brett Cannon 在 bpo-25609 中貢獻。)
datetime¶
datetime 和 time 類具有新的 fold 屬性,用於在必要時消除本地時間的歧義。datetime 中的許多函式已更新以支援本地時間消歧。有關更多資訊,請參閱 本地時間消歧 部分。(由 Alexander Belopolsky 在 bpo-24773 中貢獻。)
datetime.strftime() 和 date.strftime() 方法現在支援 ISO 8601 日期指令 %G、%u 和 %V。(由 Ashley Anderson 在 bpo-12006 中貢獻。)
datetime.isoformat() 函式現在接受可選的 timespec 引數,該引數指定要包含的時間值的附加元件的數量。(由 Alessandro Cucci 和 Alexander Belopolsky 在 bpo-19475 中貢獻。)
datetime.combine() 現在接受可選的 tzinfo 引數。(由 Alexander Belopolsky 在 bpo-27661 中貢獻。)
decimal¶
新的 Decimal.as_integer_ratio() 方法,返回一對 (n, d) 整數,表示給定的 Decimal 例項作為分數,以最簡形式和正分母
>>> Decimal('-3.14').as_integer_ratio()
(-157, 50)
(由 Stefan Krah 和 Mark Dickinson 在 bpo-25928 中貢獻。)
distutils¶
default_format 屬性已從 distutils.command.sdist.sdist 中移除,formats 屬性預設為 ['gztar']。儘管未曾預料,任何依賴於 default_format 的程式碼可能需要進行調整。有關更多詳細資訊,請參見 bpo-27819。
email¶
透過建構函式的 policy 關鍵字啟用的新 email API 不再是臨時性的。email 文件已重新組織和重寫,以專注於新 API,同時保留舊文件用於傳統 API。(由 R. David Murray 在 bpo-24277 中貢獻。)
email.mime 類現在都接受可選的 policy 關鍵字。(由 Berker Peksag 在 bpo-27331 中貢獻。)
DecodedGenerator 現在支援 policy 關鍵字。
有一個新的 policy 屬性 message_factory,它控制解析器建立新訊息物件時預設使用的類。對於 email.policy.compat32 策略,這是 Message,對於新策略,它是 EmailMessage。(由 R. David Murray 在 bpo-20476 中貢獻。)
encodings¶
在 Windows 上,添加了 'oem' 編碼以使用 CP_OEMCP,以及現有 'mbcs' 編碼的 'ansi' 別名,該編碼使用 CP_ACP 內碼表。(由 Steve Dower 在 bpo-27959 中貢獻。)
enum¶
enum 模組中添加了兩個新的列舉基類:Flag 和 IntFlag。兩者都用於定義可以使用位運算子組合的常量。(由 Ethan Furman 在 bpo-23591 中貢獻。)
許多標準庫模組已更新,以使用 IntFlag 類作為其常量。
新的 enum.auto 值可用於自動為列舉成員賦值
>>> from enum import Enum, auto
>>> class Color(Enum):
... red = auto()
... blue = auto()
... green = auto()
...
>>> list(Color)
[<Color.red: 1>, <Color.blue: 2>, <Color.green: 3>]
faulthandler¶
在 Windows 上,faulthandler 模組現在為 Windows 異常安裝了一個處理程式:請參見 faulthandler.enable()。(由 Victor Stinner 在 bpo-23848 中貢獻。)
fileinput¶
hook_encoded() 現在支援 errors 引數。(由 Joseph Hackman 在 bpo-25788 中貢獻。)
hashlib¶
hashlib 支援 OpenSSL 1.1.0。建議的最低版本是 1.0.2。(由 Christian Heimes 在 bpo-26470 中貢獻。)
BLAKE2 雜湊函式已新增到模組中。blake2b() 和 blake2s() 始終可用,並支援 BLAKE2 的全部功能集。(由 Christian Heimes 在 bpo-26798 中貢獻,基於 Dmitry Chestnykh 和 Samuel Neves 的程式碼。文件由 Dmitry Chestnykh 編寫。)
SHA-3 雜湊函式 sha3_224()、sha3_256()、sha3_384()、sha3_512(),以及 SHAKE 雜湊函式 shake_128() 和 shake_256() 已新增。(由 Christian Heimes 在 bpo-16113 中貢獻。Keccak 程式碼包由 Guido Bertoni、Joan Daemen、Michaël Peeters、Gilles Van Assche 和 Ronny Van Keer 貢獻。)
密碼派生函式 scrypt() 現在可用於 OpenSSL 1.1.0 及更高版本。(由 Christian Heimes 在 bpo-27928 中貢獻。)
http.client¶
HTTPConnection.request() 和 endheaders() 現在都支援分塊編碼請求體。(由 Demian Brecht 和 Rolf Krahl 在 bpo-12319 中貢獻。)
idlelib 和 IDLE¶
idlelib 包正在現代化和重構,以使 IDLE 外觀和工作更好,並使程式碼更易於理解、測試和改進。使 IDLE 外觀更好(尤其是在 Linux 和 Mac 上)的一部分是使用 ttk 小部件,主要在對話方塊中。因此,IDLE 不再與 tcl/tk 8.4 一起執行。現在它需要 tcl/tk 8.5 或 8.6。我們建議執行任何一個的最新版本。
“現代化”包括 idlelib 模組的重新命名和整合。部分大寫名稱的檔案的重新命名類似於 3.0 中 Tkinter 和 TkFont 重新命名為 tkinter 和 tkinter.font。因此,在 3.5 中有效的 idlelib 檔案匯入通常在 3.6 中無效。至少需要更改模組名稱(請參見 idlelib/README.txt),有時需要更多。(名稱更改由 Al Swiegart 和 Terry Reedy 在 bpo-24225 中貢獻。此後的大多數 idlelib 補丁已並將成為該過程的一部分。)
作為補償,最終結果將是某些 idlelib 類將更容易使用,具有更好的 API 和解釋它們的文件字串。當可用時,將向 idlelib 新增更多有用資訊。
3.6.2 中的新增功能
自動補全的多次修復。(由Louie Lu在bpo-15786貢獻。)
3.6.3 版新增
模組瀏覽器(在“檔案”選單中,以前稱為“類瀏覽器”)現在除了頂級函式和類之外,還顯示巢狀函式和類。(由Guilherme Polo、Cheryl Sabella和Terry Jan Reedy在bpo-1612262貢獻。)
以前作為擴充套件實現的IDLE功能已重新實現為常規功能。它們的設定已從“擴充套件”選項卡移至其他對話方塊選項卡。(由Charles Wohlganger和Terry Jan Reedy在bpo-27099貢獻。)
“設定”對話方塊(選項,配置IDLE)已部分重寫,以改善外觀和功能。(由Cheryl Sabella和Terry Jan Reedy在多個問題中貢獻。)
3.6.4 版新增
字型樣本現在包含一系列非拉丁字元,以便使用者更好地檢視選擇特定字型的效果。(由Terry Jan Reedy在bpo-13802貢獻。)樣本可以編輯以包含其他字元。(由Serhiy Storchaka在bpo-31860貢獻。)
3.6.6 版新增
編輯器程式碼上下文選項已修訂。框顯示所有上下文行,最多顯示 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.6.7 版新增
超出 N 行(預設為 50 行)的輸出會被壓縮成一個按鈕。N 可以在“設定”對話方塊的“通用”頁面的“PyShell”部分更改。透過右鍵單擊輸出,可以壓縮更少但可能過長的行。壓縮後的輸出可以透過雙擊按鈕在原地展開,或透過右鍵單擊按鈕展開到剪貼簿或單獨的視窗中。(由 Tal Einat 在bpo-1529353中貢獻。)
importlib¶
當無法找到模組時,import 現在會引發新的異常 ModuleNotFoundError (它是 ImportError 的子類)。當前檢查 ImportError (在 try-except 中) 的程式碼仍然有效。(由Eric Snow在bpo-15767貢獻。)
importlib.util.LazyLoader 現在會在包裝的載入器上呼叫 create_module(),移除了 importlib.machinery.BuiltinImporter 和 importlib.machinery.ExtensionFileLoader 不能與 importlib.util.LazyLoader 一起使用的限制。
importlib.util.cache_from_source()、importlib.util.source_from_cache() 和 importlib.util.spec_from_file_location() 現在接受 類路徑物件。
inspect¶
inspect.signature() 函式現在將編譯器為推導式和生成器表示式作用域生成的隱式 .0 引數報告為名為 implicit0 的僅位置引數。(由Jelle Zijlstra在bpo-19611貢獻。)
為了減少從 Python 2.7 和舊版 inspect.getargspec() API 升級時的程式碼修改,之前記錄的 inspect.getfullargspec() 的棄用已被撤銷。雖然此函式對於單/源 Python 2/3 程式碼庫很方便,但更豐富的 inspect.signature() 介面仍然是新程式碼的推薦方法。(由Nick Coghlan在bpo-27172貢獻)
json¶
json.load() 和 json.loads() 現在支援二進位制輸入。編碼的 JSON 應該使用 UTF-8、UTF-16 或 UTF-32 表示。(由Serhiy Storchaka在bpo-17909貢獻。)
logging¶
新增了 WatchedFileHandler.reopenIfNeeded() 方法,以增加檢查日誌檔案是否需要重新開啟的功能。(由Marian Horban在bpo-24884貢獻。)
math¶
常數 tau (τ) 已新增到 math 和 cmath 模組中。(由Lisa Roach在bpo-12345貢獻,詳見 PEP 628。)
multiprocessing¶
multiprocessing.Manager() 返回的 代理物件 現在可以巢狀。(由Davin Potts在bpo-6766貢獻。)
os¶
有關 PEP 519 的摘要,請參閱 os 和 os.path 模組現在如何支援 類路徑物件 的詳細資訊。
scandir() 現在支援 Windows 上的 bytes 路徑。
新增了 close() 方法,允許顯式關閉 scandir() 迭代器。scandir() 迭代器現在支援 上下文管理器 協議。如果 scandir() 迭代器既未耗盡也未顯式關閉,則在其解構函式中會發出 ResourceWarning 警告。(由Serhiy Storchaka在bpo-25994貢獻。)
在 Linux 上,os.urandom() 現在會阻塞,直到系統 urandom 熵池初始化以提高安全性。有關理由,請參閱 PEP 524。
Linux getrandom() 系統呼叫(獲取隨機位元組)現在作為新的 os.getrandom() 函式公開。(由Victor Stinner貢獻,是 PEP 524 的一部分)
pathlib¶
pathlib 現在支援 類路徑物件。(由Brett Cannon在bpo-27186貢獻。)
有關詳細資訊,請參閱 PEP 519 的摘要。
pdb¶
Pdb 類建構函式新增了可選的 readrc 引數,用於控制是否應該讀取 .pdbrc 檔案。
pickle¶
需要使用關鍵字引數呼叫 __new__ 的物件現在可以使用早於協議版本 4 的 pickle 協議 進行 pickle。協議版本 4 已經支援這種情況。(由Serhiy Storchaka在bpo-24164貢獻。)
pickletools¶
pickletools.dis() 現在為 MEMOIZE 操作碼輸出隱式備忘錄索引。(由Serhiy Storchaka在bpo-25382貢獻。)
pydoc¶
pydoc 模組已經學會了遵循 MANPAGER 環境變數。(由Matthias Klose在bpo-8637貢獻。)
help() 和 pydoc 現在可以按定義順序而不是按字母順序列出命名元組欄位。(由Raymond Hettinger在bpo-24879貢獻。)
random¶
新的 choices() 函式返回一個指定大小的元素列表,該列表從給定總體中獲取,並帶有可選的權重。(由Raymond Hettinger在bpo-18844貢獻。)
re¶
增加了對正則表示式中修飾符範圍的支援。例如:'(?i:p)ython' 匹配 'python' 和 'Python',但不匹配 'PYTHON';'(?i)g(?-i:v)r' 匹配 'GvR' 和 'gvr',但不匹配 'GVR'。(由Serhiy Storchaka在bpo-433028貢獻。)
匹配物件組可以透過 __getitem__ 訪問,這等同於 group()。因此 mo['name'] 現在等同於 mo.group('name')。(由Eric Smith在bpo-24454貢獻。)
Match 物件現在支援 類索引物件 作為組索引。(由Jeroen Demeyer和Xiang Zhang在bpo-27177貢獻。)
readline¶
添加了 set_auto_history() 來啟用或停用自動將輸入新增到歷史列表。(由Tyler Crompton在bpo-26870貢獻。)
rlcompleter¶
私有和特殊屬性名稱現在被省略,除非字首以下劃線開頭。某些已完成的關鍵字後面會新增一個空格或冒號。(由Serhiy Storchaka在bpo-25011和bpo-25209貢獻。)
shlex¶
shlex 透過新的 punctuation_chars 引數來控制哪些字元被視為標點符號,從而大大改進了 shell 相容性。(由Vinay Sajip在bpo-1521950貢獻。)
site¶
在 .pth 檔案中指定要新增到 sys.path 的路徑時,現在可以在目錄(例如 zip 檔案)之上指定檔案路徑。(由Wolfgang Langner在bpo-26587貢獻)。
sqlite3¶
sqlite3.Cursor.lastrowid 現在支援 REPLACE 語句。(由Alex LordThorsen在bpo-16864貢獻。)
socket¶
ioctl() 函式現在支援 SIO_LOOPBACK_FAST_PATH 控制程式碼。(由Daniel Stokes在bpo-26536貢獻。)
現在支援 getsockopt() 常量 SO_DOMAIN、SO_PROTOCOL、SO_PEERSEC 和 SO_PASSSEC。(由Christian Heimes在bpo-26907貢獻。)
setsockopt() 現在支援 setsockopt(level, optname, None, optlen: int) 形式。(由Christian Heimes在bpo-27744貢獻。)
socket 模組現在支援地址族 AF_ALG,以與 Linux 核心加密 API 互動。添加了 ALG_*、SOL_ALG 和 sendmsg_afalg()。(由Christian Heimes在bpo-27744貢獻,並得到了Victor Stinner的支援。)
新增了 Linux 常量 TCP_USER_TIMEOUT 和 TCP_CONGESTION。(由Omar Sandoval在bpo-26273貢獻。)
socketserver¶
基於 socketserver 模組的伺服器,包括 http.server、xmlrpc.server 和 wsgiref.simple_server 中定義的伺服器,現在支援 上下文管理器 協議。(由Aviv Palivoda在bpo-26404貢獻。)
StreamRequestHandler 類的 wfile 屬性現在實現了 io.BufferedIOBase 可寫介面。特別是,現在保證呼叫 write() 會完全傳送資料。(由Martin Panter在bpo-26721貢獻。)
ssl¶
ssl 支援 OpenSSL 1.1.0。建議的最低版本是 1.0.2。(由Christian Heimes在bpo-26470貢獻。)
3DES 已從預設密碼套件中移除,並添加了 ChaCha20 Poly1305 密碼套件。(由Christian Heimes在bpo-27850和bpo-27766貢獻。)
SSLContext 對選項和密碼具有更好的預設配置。(由Christian Heimes在bpo-28043貢獻。)
SSL 會話可以使用新的 SSLSession 類從一個客戶端連線複製到另一個客戶端連線。TLS 會話恢復可以加快初始握手,減少延遲並提高效能。(由Christian Heimes在bpo-19500貢獻,基於Alex Warhawk的草稿。)
可以使用新的 get_ciphers() 方法獲取按密碼優先順序排序的已啟用密碼列表。
所有常量和標誌都已轉換為 IntEnum 和 IntFlag。(由Christian Heimes在bpo-28025貢獻。)
為 SSLContext 添加了伺服器端和客戶端特定的 TLS 協議。(由Christian Heimes在bpo-28085貢獻。)
新增了 ssl.SSLContext.post_handshake_auth 用於啟用,以及 ssl.SSLSocket.verify_client_post_handshake() 用於啟動 TLS 1.3 握手後認證。(由Christian Heimes在gh-78851貢獻。)
statistics¶
新增了 harmonic_mean() 函式。(由Steven D’Aprano在bpo-27181貢獻。)
struct¶
struct 現在透過 'e' 格式說明符支援 IEEE 754 半精度浮點數。(由Eli Stevens、Mark Dickinson在bpo-11734貢獻。)
subprocess¶
subprocess.Popen 解構函式現在會在子程序仍在執行時發出 ResourceWarning 警告。使用上下文管理器協議 (with proc: ...) 或顯式呼叫 wait() 方法來讀取子程序的退出狀態。(由Victor Stinner在bpo-26741貢獻。)
subprocess.Popen 建構函式和所有透過它傳遞引數的函式現在都接受 encoding 和 errors 引數。指定其中任何一個都將為 stdin、stdout 和 stderr 流啟用文字模式。(由Steve Dower在bpo-6135貢獻。)
sys¶
新的 getfilesystemencodeerrors() 函式返回用於在 Unicode 檔名和位元組檔名之間轉換的錯誤模式的名稱。(由Steve Dower在bpo-27781貢獻。)
在 Windows 上,getwindowsversion() 函式的返回值現在包含 platform_version 欄位,其中包含當前作業系統的準確主要版本、次要版本和構建號,而不是為程序模擬的版本。(由Steve Dower在bpo-27932貢獻。)
telnetlib¶
telnetlib.Telnet 現在是一個上下文管理器(由Stéphane Wirtel在bpo-25485貢獻)。
時間¶
struct_time 屬性 tm_gmtoff 和 tm_zone 現在在所有平臺上可用。
timeit¶
新的 Timer.autorange() 便捷方法已被新增,用於重複呼叫 Timer.timeit(),以便總執行時間大於或等於 200 毫秒。(由Steven D’Aprano在bpo-6422貢獻。)
timeit 現在會在最佳時間和最差時間之間存在顯著(4 倍)差異時發出警告。(由Serhiy Storchaka在bpo-23552貢獻。)
tkinter¶
在 tkinter.Variable 類中添加了方法 Variable.trace_add()、Variable.trace_remove() 和 trace_info()。它們替換了使用過時 Tcl 命令且可能在未來 Tcl 版本中不起作用的舊方法 trace_variable()、trace()、trace_vdelete() 和 trace_vinfo()。(由Serhiy Storchaka在bpo-22115貢獻)。
traceback¶
追溯模組和直譯器的內建異常顯示現在都會縮寫追溯中重複行的長序列,如以下示例所示
>>> def f(): f()
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in f
File "<stdin>", line 1, in f
File "<stdin>", line 1, in f
[Previous line repeated 995 more times]
RecursionError: maximum recursion depth exceeded
(由Emanuel Barry在bpo-26823貢獻。)
tracemalloc¶
tracemalloc 模組現在支援在多個不同地址空間中追蹤記憶體分配。
新增了 DomainFilter 過濾器類,用於按地址空間(域)過濾塊跟蹤。
(由Victor Stinner在bpo-26588貢獻。)
typing¶
由於 typing 模組是 臨時性API,因此 Python 3.6 中引入的所有更改也已向後移植到 Python 3.5.x。
typing 模組大大改進了對泛型類型別名的支援。例如,Dict[str, Tuple[S, T]] 現在是有效的型別註解。(由Guido van Rossum在Github #195貢獻。)
新增了 typing.ContextManager 類,用於表示 contextlib.AbstractContextManager。(由Brett Cannon在bpo-25609貢獻。)
新增了 typing.Collection 類,用於表示 collections.abc.Collection。(由Ivan Levkivskyi在bpo-27598貢獻。)
添加了 typing.ClassVar 型別結構以標記類變數。如 PEP 526 中介紹的,用 ClassVar 包裝的變數註解表示給定屬性旨在用作類變數,不應在類的例項上設定。(由Ivan Levkivskyi在Github #280貢獻。)
一個新的 TYPE_CHECKING 常量,靜態型別檢查器假定它為 True,但在執行時為 False。(由Guido van Rossum在Github #230貢獻。)
新增了 NewType() 輔助函式,用於為註解建立輕量級、不同的型別。
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
靜態型別檢查器會將新型別視為原始型別的子類。(由Ivan Levkivskyi在Github #189貢獻。)
unicodedata¶
unicodedata 模組現在使用 Unicode 9.0.0 的資料。(由Benjamin Peterson貢獻。)
unittest.mock¶
Mock 類具有以下改進
兩個新方法,
Mock.assert_called()和Mock.assert_called_once(),用於檢查模擬物件是否被呼叫。(由Amit Saha在bpo-26323貢獻。)Mock.reset_mock()方法現在有兩個可選的僅限關鍵字引數:return_value 和 side_effect。(由Kushal Das在bpo-21271貢獻。)
urllib.request¶
如果 HTTP 請求有一個檔案或可迭代主體(除了位元組物件),但沒有 Content-Length 頭部,AbstractHTTPHandler 現在不會丟擲錯誤,而是回退到使用分塊傳輸編碼。(由Demian Brecht和Rolf Krahl在bpo-12319貢獻。)
urllib.robotparser¶
RobotFileParser 現在支援 Crawl-delay 和 Request-rate 擴充套件。(由Nikolay Bogoychev在bpo-16099貢獻。)
venv¶
venv 接受一個新的引數 --prompt。此引數為虛擬環境提供了另一個字首。(由Łukasz Balcerzak提出,並由Stéphane Wirtel移植到 3.6,在bpo-22829中。)
warnings¶
warnings.warn_explicit() 函式新增了一個可選的 source 引數:發出 ResourceWarning 的銷燬物件。warnings.WarningMessage 也新增了 source 屬性(由Victor Stinner在bpo-26568和bpo-26567貢獻)。
當記錄 ResourceWarning 警告時,現在使用 tracemalloc 模組嘗試檢索銷燬物件分配時的追溯。
使用指令碼 example.py 的示例
import warnings
def func():
return open(__file__)
f = func()
f = None
命令 python3.6 -Wd -X tracemalloc=5 example.py 的輸出
example.py:7: ResourceWarning: unclosed file <_io.TextIOWrapper name='example.py' mode='r' encoding='UTF-8'>
f = None
Object allocated at (most recent call first):
File "example.py", lineno 4
return open(__file__)
File "example.py", lineno 6
f = func()
“物件分配於”追溯是新增的,並且僅在 tracemalloc 正在追蹤 Python 記憶體分配且 warnings 模組已匯入時顯示。
winreg¶
winsound¶
允許將關鍵字引數傳遞給 Beep、MessageBeep 和 PlaySound (bpo-27982)。
xmlrpc.client¶
xmlrpc.client 模組現在支援解組 Apache XML-RPC 實現用於數值和 None 的其他資料型別。(由Serhiy Storchaka在bpo-26885貢獻。)
zipfile¶
新的 ZipInfo.from_file() 類方法允許從檔案系統檔案建立 ZipInfo 例項。新的 ZipInfo.is_dir() 方法可用於檢查 ZipInfo 例項是否表示目錄。(由Thomas Kluyver在bpo-26039貢獻。)
ZipFile.open() 方法現在可以用於向 ZIP 檔案寫入資料,以及提取資料。(由Thomas Kluyver在bpo-26039貢獻。)
zlib¶
compress() 和 decompress() 函式現在接受關鍵字引數。(分別由Aviv Palivoda在bpo-26243和Xiang Zhang在bpo-16764貢獻。)
最佳化¶
Python 直譯器現在使用 16 位字碼而不是位元組碼,這使得許多操作碼最佳化成為可能。(由Demur Rumed在Serhiy Storchaka和Victor Stinner的輸入和審查下,在bpo-26647和bpo-28050中貢獻。)
asyncio.Future類現在有了最佳化的 C 實現。(由Yury Selivanov和INADA Naoki在bpo-26081貢獻。)asyncio.Task類現在有了最佳化的 C 實現。(由Yury Selivanov在bpo-28544貢獻。)typing模組中的各種實現改進(例如泛型型別的快取)可將效能提高多達 30 倍,並減少記憶體佔用。ASCII 解碼器對於錯誤處理程式
surrogateescape、ignore和replace現在速度提高了 60 倍。(由Victor Stinner在bpo-24870貢獻)。ASCII 和 Latin1 編碼器對於錯誤處理程式
surrogateescape現在速度提高了 3 倍。(由Victor Stinner在bpo-25227貢獻)。UTF-8 編碼器對於錯誤處理程式
ignore、replace、surrogateescape、surrogatepass現在速度提高了 75 倍。(由Victor Stinner在bpo-25267貢獻)。UTF-8 解碼器對於錯誤處理程式
ignore、replace和surrogateescape現在速度提高了 15 倍。(由Victor Stinner在bpo-25301貢獻)。bytes % args現在快了兩倍。(由Victor Stinner在bpo-25349貢獻)。bytearray % args現在快了 2.5 到 5 倍。(由Victor Stinner在bpo-25399貢獻)。最佳化
bytes.fromhex()和bytearray.fromhex():它們現在快了 2 倍到 3.5 倍。(由Victor Stinner在bpo-25401貢獻)。最佳化
bytes.replace(b'', b'.')和bytearray.replace(b'', b'.'):速度提高了高達 80%。(由Josh Snider在bpo-26574貢獻)。PyMem_Malloc()域 (PYMEM_DOMAIN_MEM) 的分配器函式現在使用 pymalloc 記憶體分配器,而不是 C 庫的malloc()函式。pymalloc 分配器針對小於或等於 512 位元組且生命週期短的物件進行了最佳化,並對較大的記憶體塊使用malloc()。(由Victor Stinner在bpo-26249貢獻。)反序列化許多小物件時,
pickle.load()和pickle.loads()現在速度提高了 10%。(由Victor Stinner在bpo-27056貢獻)。與傳遞 位置引數 相比,向函式傳遞 關鍵字引數 存在開銷。現在,在使用 Argument Clinic 實現的擴充套件函式中,這種開銷已顯著降低。(由Serhiy Storchaka在bpo-27574貢獻。)
優化了
glob模組中的glob()和iglob()函式;它們現在快了大約 3-6 倍。(由Serhiy Storchaka在bpo-25596貢獻。)透過使用
os.scandir(),優化了pathlib中的 globbing;現在速度提高了大約 1.5-4 倍。(由Serhiy Storchaka在bpo-26032貢獻。)xml.etree.ElementTree的解析、迭代和深層複製效能已顯著提高。(由Serhiy Storchaka在bpo-25638、bpo-25873和bpo-25869貢獻。)從浮點數和小數建立
fractions.Fraction例項現在快了 2 到 3 倍。(由Serhiy Storchaka在bpo-25971貢獻。)
構建和 C API 更改¶
Python 現在在構建工具鏈時需要一些 C99 支援。最值得注意的是,Python 現在使用標準整數型別和宏,而不是像
PY_LONG_LONG這樣的自定義宏。有關更多資訊,請參閱 PEP 7 和 bpo-17884。使用 Android NDK 和 Android API 級別設定為 21 (Android 5.0 Lollipop) 或更高版本交叉編譯 CPython 成功執行。雖然 Android 尚未成為受支援的平臺,但 Python 測試套件在 Android 模擬器上執行,只有大約 16 個測試失敗。請參閱 Android 元問題 bpo-26865。
添加了
--enable-optimizations配置標誌。啟用它將啟用昂貴的最佳化,例如 PGO。(英特爾的Alecsandru Patrascu在bpo-26359中貢獻的原始補丁。)現在,當呼叫
PYMEM_DOMAIN_OBJ(例如:PyObject_Malloc())和PYMEM_DOMAIN_MEM(例如:PyMem_Malloc())域的分配器函式時,必須持有 GIL。新的
Py_FinalizeEx()API,指示重新整理緩衝資料是否失敗。(由Martin Panter在bpo-5319貢獻。)PyArg_ParseTupleAndKeywords()現在支援 僅位置引數。僅位置引數由空名稱定義。(由Serhiy Storchaka在bpo-26282貢獻)。PyTraceback_Print方法現在將重複行的長序列縮寫為"[Previous line repeated {count} more times]"。(由Emanuel Barry在bpo-26823貢獻。)新的
PyErr_SetImportErrorSubclass()函式允許指定ImportError的子類以引發。(由Eric Snow在bpo-15767貢獻。)新的
PyErr_ResourceWarning()函式可用於生成ResourceWarning,提供資源分配的來源。(由Victor Stinner在bpo-26567貢獻。)新的
PyOS_FSPath()函式返回 類路徑物件 的檔案系統表示。(由Brett Cannon在bpo-27186貢獻。)PyUnicode_FSConverter()和PyUnicode_FSDecoder()函式現在將接受 類路徑物件。
其他改進¶
當
--version(短形式:-V) 被提供兩次時,Python 會列印sys.version以獲取詳細資訊。$ ./python -VV Python 3.6.0b4+ (3.6:223967b49e49+, Nov 21 2016, 20:55:04) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
已棄用¶
新關鍵字¶
async 和 await 不建議用作變數、類、函式或模組名稱。它們由 Python 3.5 中的 PEP 492 引入,將在 Python 3.7 中成為正式關鍵字。從 Python 3.6 開始,使用 async 或 await 作為名稱將生成 DeprecationWarning。
已棄用的 Python 行為¶
在生成器內部引發 StopIteration 異常現在會生成 DeprecationWarning,並將在 Python 3.7 中觸發 RuntimeError。詳見 PEP 479:更改生成器內部的 StopIteration 處理方式。
__aiter__() 方法現在期望直接返回一個非同步迭代器,而不是像以前那樣返回一個可等待物件。執行前者將觸發 DeprecationWarning。向後相容性將在 Python 3.7 中移除。(由Yury Selivanov在bpo-27243貢獻。)
不是有效轉義序列的反斜槓字元對現在會生成 DeprecationWarning。雖然這最終會變成 SyntaxError,但這不會在幾個 Python 版本內發生。(由Emanuel Barry在bpo-27364貢獻。)
執行相對匯入時,當 __spec__ 或 __package__ 未定義時,回退到呼叫模組的 __name__ 和 __path__ 現在會引發 ImportWarning。(由Rose Ames在bpo-25791貢獻。)
已棄用的 Python 模組、函式和方法¶
asynchat¶
asyncore¶
dbm¶
與其他 dbm 實現不同,dbm.dumb 模組以 'rw' 模式建立資料庫,並允許修改以 'r' 模式開啟的資料庫。此行為現已棄用,並將在 3.8 版中移除。(由Serhiy Storchaka在bpo-21708貢獻。)
distutils¶
distutils.Distribution 建構函式中未文件化的 extra_path 引數現在被視為已棄用,如果設定,將引發警告。對該引數的支援將在未來的 Python 版本中移除。詳見 bpo-27919。
grp¶
getgrgid() 中對非整數引數的支援已棄用。(由Serhiy Storchaka在bpo-26129貢獻。)
importlib¶
importlib.machinery.SourceFileLoader.load_module() 和 importlib.machinery.SourcelessFileLoader.load_module() 方法現已棄用。它們是 importlib 中 importlib.abc.Loader.load_module() 僅存的實現,在之前的 Python 版本中尚未被棄用,取而代之的是 importlib.abc.Loader.exec_module()。
importlib.machinery.WindowsRegistryFinder 類現已棄用。截至 3.6.0 版本,它預設仍被新增到 sys.meta_path (在 Windows 上),但這在未來的版本中可能會改變。
os¶
在 os 函式、compile() 和類似函式中,將一般 bytes-like objects 作為路徑的未文件化支援現已棄用。(由 Serhiy Storchaka 在 bpo-25791 和 bpo-26754 中貢獻。)
re¶
正則表示式中間的內聯標誌 (?letters) 的支援已棄用,並將在未來的 Python 版本中移除。正則表示式開頭的標誌仍然允許。(由 Serhiy Storchaka 在 bpo-22493 中貢獻。)
ssl¶
OpenSSL 0.9.8, 1.0.0 和 1.0.1 已棄用,不再受支援。未來,ssl 模組將至少需要 OpenSSL 1.0.2 或 1.1.0。
ftplib、http.client、imaplib、poplib 和 smtplib 中與 SSL 相關的引數,如 certfile、keyfile 和 check_hostname,已棄用,取而代之的是 context。(由 Christian Heimes 在 bpo-28022 中貢獻。)
ssl 模組的幾個協議和函式現已棄用。某些功能在未來的 OpenSSL 版本中將不再可用。其他功能則因偏好不同的 API 而棄用。(由 Christian Heimes 在 bpo-28022 和 bpo-26470 中貢獻。)
tkinter¶
tkinter.tix 模組現已棄用。tkinter 使用者應改為使用 tkinter.ttk。
venv¶
pyvenv 指令碼已棄用,取而代之的是 python3 -m venv。這可以防止 pyvenv 與哪個 Python 直譯器關聯以及虛擬環境將使用哪個 Python 直譯器造成混淆。(由 Brett Cannon 在 bpo-25154 中貢獻。)
xml¶
為了緩解 DTD 和外部實體檢索問題,
xml.dom.minidom和xml.sax模組預設不再處理外部實體。(由 Christian Heimes 在 gh-61441 中貢獻。)
已棄用的 C API 函式和型別¶
未文件化的函式 PyUnicode_AsEncodedObject()、PyUnicode_AsDecodedObject()、PyUnicode_AsEncodedUnicode() 和 PyUnicode_AsDecodedUnicode() 現已棄用。請改用通用基於編解碼器的 API。
棄用的構建選項¶
在非 macOS 的 UNIX 平臺上,--with-system-ffi 配置標誌現在預設為開啟。可以透過使用 --without-system-ffi 停用它,但使用此標誌已棄用,並且在 Python 3.7 中將不被接受。macOS 不受此更改的影響。請注意,許多作業系統發行商在構建其系統 Python 時已使用 --with-system-ffi 標誌。
已移除¶
API 和功能移除¶
正則表示式中由
'\'和 ASCII 字母組成的未知轉義序列現在將導致錯誤。在re.sub()的替換模板中,它們仍然允許,但已棄用。re.LOCALE標誌現在只能與二進位制模式一起使用。inspect.getmoduleinfo()已移除(自 CPython 3.3 起已棄用)。應使用inspect.getmodulename()來獲取給定路徑的模組名稱。(由 Yury Selivanov 在 bpo-13248 中貢獻。)traceback.Ignore類以及traceback.usage、traceback.modname、traceback.fullmodname、traceback.find_lines_from_code、traceback.find_lines、traceback.find_strings、traceback.find_executable_lines方法已從traceback模組中移除。它們是自 Python 3.2 以來已棄用的未文件化方法,並且等效功能可透過私有方法獲得。tkinter小部件類中的tk_menuBar()和tk_bindForTraversal()虛擬方法已移除(相應的 Tk 命令自 Tk 4.0 起已過時)。zipfile.ZipFile類的open()方法不再支援'U'模式(自 Python 3.4 起已棄用)。在 通用換行符 模式下讀取壓縮文字檔案,請使用io.TextIOWrapper。未文件化的
IN、CDROM、DLFCN、TYPES、CDIO和STROPTS模組已移除。它們曾位於平臺特定的Lib/plat-*/目錄中,但長期過時、跨平臺可用性不一致且無人維護。建立這些模組的指令碼仍然可以在原始碼分發中的 Tools/scripts/h2py.py 找到。已棄用的
asynchat.fifo類已移除。
移植到 Python 3.6¶
本節列出了前面描述過的變更以及其他可能需要修改程式碼的 bug 修復。
“python” 命令列為的更改¶
透過定義
COUNT_ALLOCS、SHOW_ALLOC_COUNT或SHOW_TRACK_COUNT宏構建的特殊 Python 的輸出現在預設關閉。可以使用-X showalloccount選項重新啟用。它現在輸出到stderr而不是stdout。(由 Serhiy Storchaka 在 bpo-23034 中貢獻。)
Python API 的變化¶
open()將不再允許將'U'模式標誌與'+'組合使用。(由 Jeff Balogh 和 John O’Connor 在 bpo-2091 中貢獻。)sqlite3不再在 DDL 語句之前隱式提交開啟的事務。在 Linux 上,
os.urandom()現在會阻塞,直到系統 urandom 熵池初始化完畢,以提高安全性。當定義了
importlib.abc.Loader.exec_module()時,也必須定義importlib.abc.Loader.create_module()。PyErr_SetImportError()現在在其 msg 引數未設定時丟擲TypeError。之前只返回NULL。程式碼物件的
co_lnotab屬性的格式已更改,以支援負行號增量。預設情況下,Python 不會發出具有負行號增量的位元組碼。使用frame.f_lineno、PyFrame_GetLineNumber()或PyCode_Addr2Line()的函式不受影響。直接解碼co_lnotab的函式應更新以使用帶符號的 8 位整數型別作為行號增量,但這僅在支援使用負行號增量的應用程式時才需要。有關co_lnotab格式及其解碼方式,請參閱Objects/lnotab_notes.txt,有關理由,請參閱 PEP 511。compileall模組中的函式現在返回布林值而不是1或0,分別表示成功或失敗。由於布林值是整數的子類,因此這隻會在您對1或0進行身份檢查時才是一個問題。請參閱 bpo-25768。讀取
urllib.parse.urlsplit()和urlparse()結果的port屬性現在對於超出範圍的值會引發ValueError,而不是返回None。參見 bpo-20059。imp模組現在會引發DeprecationWarning而不是PendingDeprecationWarning。以下模組已將其缺少的 API 新增到它們的
__all__屬性中,以匹配文件化的 API:calendar、cgi、csv、ElementTree、enum、fileinput、ftplib、logging、mailbox、mimetypes、optparse、plistlib、smtpd、subprocess、tarfile、threading和wave。這意味著當使用import *時,它們將匯出新的符號。(由 Joel Taddei 和 Jacek Kołodziej 在 bpo-23883 中貢獻。)執行相對匯入時,如果
__package__與__spec__.parent不相等,則會引發ImportWarning。(由 Brett Cannon 在 bpo-25791 中貢獻。)當執行相對匯入且沒有已知父包時,將引發
ImportError。以前可能會引發SystemError。(由 Brett Cannon 在 bpo-18018 中貢獻。)基於
socketserver模組的伺服器,包括那些在http.server、xmlrpc.server和wsgiref.simple_server中定義的伺服器,現在只捕獲派生自Exception的異常。因此,如果請求處理程式引發像SystemExit或KeyboardInterrupt這樣的異常,handle_error()將不再被呼叫,並且異常將停止單執行緒伺服器。(由 Martin Panter 在 bpo-23430 中貢獻。)spwd.getspnam()現在如果使用者沒有許可權,會引發PermissionError而不是KeyError。socket.socket.close()方法現在在底層系統呼叫報告錯誤(例如EBADF)時會引發異常。(由 Martin Panter 在 bpo-26685 中貢獻。)smtpd.SMTPChannel和smtpd.SMTPServer建構函式的 decode_data 引數現在預設為False。這意味著傳遞給process_message()的引數現在預設是一個位元組物件,並且process_message()將傳遞關鍵字引數。已經根據 3.5 版本生成的棄用警告進行更新的程式碼將不受影響。json模組中dump()、dumps()、load()和loads()函式以及JSONEncoder和JSONDecoder類建構函式的所有可選引數現在都是僅限關鍵字的。(由 Serhiy Storchaka 在 bpo-18726 中貢獻。)type的子類,如果不覆蓋type.__new__,可能無法再使用單引數形式來獲取物件的型別。作為 PEP 487 的一部分,傳遞給
type的關鍵字引數(除了元類提示metaclass)的處理現在始終委託給object.__init_subclass__()。這意味著type.__new__和type.__init__現在都接受任意關鍵字引數,但object.__init_subclass__()(它從type.__new__呼叫)預設會拒絕它們。接受額外關鍵字引數的自定義元類需要相應地調整它們對type.__new__的呼叫(無論是直接呼叫還是透過super呼叫)。在
distutils.command.sdist.sdist中,default_format屬性已移除,不再生效。相反,gzipped tarfile 格式在所有平臺上都是預設格式,不再進行平臺特定的選擇。在 Windows 上構建分發版且需要 zip 分發版的環境中,請使用包含以下內容的setup.cfg檔案配置專案:[sdist] formats=zip
此行為也已透過 Setuptools 26.0.0 回溯到早期 Python 版本。
在
urllib.request模組和http.client.HTTPConnection.request()方法中,如果未指定 Content-Length 頭部欄位且請求體是檔案物件,則現在會使用 HTTP 1.1 分塊編碼傳送。如果檔案物件必須傳送到 HTTP 1.0 伺服器,則現在必須由呼叫者指定 Content-Length 值。(由 Demian Brecht 和 Rolf Krahl 貢獻,Martin Panter 在 bpo-12319 中進行了調整。)DictReader現在返回OrderedDict型別的行。(由 Steve Holden 在 bpo-27842 中貢獻。)如果平臺不支援
crypt.METHOD_CRYPT,則不再將其新增到crypt.methods。(由 Victor Stinner 在 bpo-25287 中貢獻。)namedtuple()的 verbose 和 rename 引數現在僅限關鍵字。(由 Raymond Hettinger 在 bpo-25628 中貢獻。)在 Linux 上,
ctypes.util.find_library()現在會在LD_LIBRARY_PATH中查詢共享庫。(由 Vinay Sajip 在 bpo-9998 中貢獻。)imaplib.IMAP4類現在處理從伺服器傳送的訊息中包含']'字元的標誌,以提高實際相容性。(由 Lita Cho 在 bpo-21815 中貢獻。)mmap.mmap.write()函式現在像其他寫入方法一樣返回寫入的位元組數。(由 Jakub Stasiak 在 bpo-26335 中貢獻。)pkgutil.iter_modules()和pkgutil.walk_packages()函式現在返回ModuleInfo命名元組。(由 Ramchandra Apte 在 bpo-17211 中貢獻。)re.sub()現在即使在字串中未找到模式,也會對替換模板中無效的數字組引用引發錯誤。無效組引用的錯誤訊息現在包含組索引和引用的位置。(由 SilentGhost 和 Serhiy Storchaka 在 bpo-25953 中貢獻。)zipfile.ZipFile現在將對無法識別的壓縮值引發NotImplementedError。以前會引發一個普通的RuntimeError。此外,在已關閉的 ZipFile 上呼叫ZipFile方法或在以'r'模式建立的 ZipFile 上呼叫write()方法將引發ValueError。以前,在這些情況下會引發RuntimeError。當自定義元類與零引數
super()或從方法到隱式__class__閉包變數的直接引用結合使用時,隱式__classcell__名稱空間條目現在必須傳遞給type.__new__進行初始化。否則,在 Python 3.6 中將導致DeprecationWarning,在 Python 3.8 中將導致RuntimeError。隨著
ModuleNotFoundError的引入,匯入系統的消費者可能會開始期望匯入系統替換在適當的時候引發更具體的異常,而不是不那麼具體的ImportError。為了提供與此類消費者未來的相容性,完全替換__import__()的替代匯入系統的實現者需要更新其實現,以便在完全找不到模組時引發新的子類。符合預設匯入系統外掛的實現者不需要進行任何更改,因為預設匯入系統將在適當的時候引發新的子類。
C API 的變化¶
PyMem_Malloc()分配器系列現在使用 pymalloc 分配器 而不是系統malloc()。在不持有 GIL 的情況下呼叫PyMem_Malloc()的應用程式現在可能會崩潰。將PYTHONMALLOC環境變數設定為debug以驗證應用程式中記憶體分配器的使用。請參閱 bpo-26249。
CPython 位元組碼變更¶
Python 3.6 中的位元組碼 有幾個重大更改。
Python 直譯器現在使用 16 位字碼而不是位元組碼。(由 Demur Rumed 在 Serhiy Storchaka 和 Victor Stinner 的輸入和審閱下在 bpo-26647 和 bpo-28050 中貢獻。)
新的
FORMAT_VALUE和BUILD_STRING操作碼是格式化字串字面量實現的一部分。(由 Eric Smith 在 bpo-25483 中,以及 Serhiy Storchaka 在 bpo-27078 中貢獻。)新的
BUILD_CONST_KEY_MAP操作碼用於最佳化具有常量鍵的字典的建立。(由 Serhiy Storchaka 在 bpo-27140 中貢獻。)函式呼叫操作碼已進行大量重寫,以提高效能並簡化實現。
MAKE_FUNCTION、CALL_FUNCTION、CALL_FUNCTION_KW和BUILD_MAP_UNPACK_WITH_CALL操作碼已修改,添加了新的CALL_FUNCTION_EX和BUILD_TUPLE_UNPACK_WITH_CALL,並移除了CALL_FUNCTION_VAR、CALL_FUNCTION_VAR_KW和MAKE_CLOSURE操作碼。(由 Demur Rumed 在 bpo-27095 中,以及 Serhiy Storchaka 在 bpo-27213 和 bpo-28257 中貢獻。)已新增新的
SETUP_ANNOTATIONS和STORE_ANNOTATION操作碼以支援新的變數註解語法。(由 Ivan Levkivskyi 在 bpo-27985 中貢獻。)
Python 3.6.2 中的顯著變化¶
新的 make regen-all 構建目標¶
為了簡化交叉編譯,並確保 CPython 可以可靠地編譯而無需現有 Python 版本,基於 autotools 的構建系統不再嘗試根據檔案修改時間隱式重新編譯生成的檔案。
相反,已新增新的 make regen-all 命令,以便在需要時(例如,在基於預生成版本構建了初始 Python 版本之後)強制重新生成這些檔案。
還定義了更具選擇性的重新生成目標 - 有關詳細資訊,請參閱 Makefile.pre.in。
(由 Victor Stinner 在 bpo-23404 中貢獻。)
在 3.6.2 版本中新增。
移除 make touch 構建目標¶
以前用於透過更新生成檔案修改時間來請求隱式重新生成生成檔案的 make touch 構建目標已移除。
它已被新的 make regen-all 目標取代。
(由 Victor Stinner 在 bpo-23404 中貢獻。)
在 3.6.2 版本中更改。
Python 3.6.4 中的顯著變化¶
作為公共 API 一部分的 PyExc_RecursionErrorInst 單例已被移除,因為其成員從未被清除,可能導致直譯器終結期間發生段錯誤。(由 Xavier de Gaye 在 bpo-22898 和 bpo-30697 中貢獻。)
Python 3.6.5 中的顯著變化¶
locale.localeconv() 函式現在在某些情況下臨時將 LC_CTYPE 區域設定更改為 LC_NUMERIC 區域設定。(由 Victor Stinner 在 bpo-31900 中貢獻。)
Python 3.6.7 中的顯著變化¶
xml.dom.minidom 和 xml.sax 模組預設不再處理外部實體。另請參閱 gh-61441。
在 3.6.7 中,tokenize 模組現在在提供沒有尾隨換行符的輸入時,隱式地發出一個 NEWLINE 令牌。此行為現在與 C tokenizer 在內部執行的操作匹配。(由 Ammar Askar 在 bpo-33899 中貢獻。)
Python 3.6.10 中的顯著變化¶
由於重大的安全問題,不再支援 asyncio.loop.create_datagram_endpoint() 的 reuse_address 引數。這是由於 SO_REUSEADDR 套接字選項在 UDP 中的行為。有關更多詳細資訊,請參見 loop.create_datagram_endpoint() 的文件。(由 Kyle Stanley、Antoine Pitrou 和 Yury Selivanov 在 bpo-37228 中貢獻。)
Python 3.6.13 中的顯著變化¶
早期的 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.6.14 中的顯著變化¶
一項安全修復程式改變了 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)