Python 3.4 中的新功能¶
- 作者:
R. David Murray <rdmurray@bitdance.com> (編輯)
本文介紹了 Python 3.4 相對於 3.3 的新功能。Python 3.4 於 2014 年 3 月 16 日釋出。有關詳細資訊,請參閱更新日誌。
參見
PEP 429 – Python 3.4 釋出計劃
總結 – 釋出亮點¶
新語法功能
Python 3.4 中沒有新增新的語法功能。
其他新功能
非文字編碼的編解碼器處理改進(多個問題)。
匯入系統的 ModuleSpec 型別 (PEP 451)。(影響匯入器作者。)
新庫模組
selectors
:基於select
模組原語構建的高階高效 I/O 複用(PEP 3156 的一部分)。statistics
:一個基本的數值穩定統計庫 (PEP 450)。
顯著改進的庫模組
email
有一個新子模組,contentmanager
,以及一個新的Message
子類 (EmailMessage
) 簡化了 MIME 處理 (bpo-18891)。inspect
和pydoc
模組現在能夠正確地自省更廣泛的可呼叫物件,這改進了 Pythonhelp()
系統的輸出。ipaddress
模組 API 已宣告穩定
安全改進
使新建立的檔案描述符不可繼承 (PEP 446) 以避免檔案描述符洩露給子程序。
multiprocessing
現在有一個在 Unix 上避免使用 os.fork 的選項。 spawn 和 forkserver 更安全,因為它們避免與子程序共享資料。Windows 上的
multiprocessing
子程序不再繼承父程序的所有可繼承控制代碼,只繼承必要的控制代碼。一個新的
hashlib.pbkdf2_hmac()
函式提供了 PKCS#5 基於密碼的金鑰派生函式 2。標準庫中所有支援 SSL 的模組現在都支援伺服器證書驗證,包括主機名匹配 (
ssl.match_hostname()
) 和 CRLs(證書吊銷列表,請參閱ssl.SSLContext.load_verify_locations()
)。
CPython 實現改進
利用 PEP 442,在大多數情況下,模組全域性變數在終結期間不再設定為 None (bpo-18214)。
請繼續閱讀,瞭解面向使用者的全面更改列表,包括許多其他較小的改進、CPython 最佳化、棄用和潛在的移植問題。
新功能¶
PEP 453:Python 安裝中 PIP 的顯式引導¶
預設引導 pip¶
新的 ensurepip
模組(在 PEP 453 中定義)提供了一個標準的跨平臺機制,用於將 pip 安裝程式引導到 Python 安裝和虛擬環境中。Python 3.4.0 中包含的 pip
版本是 pip
1.5.4,未來的 3.4.x 維護版本將把捆綁版本更新到建立釋出候選版本時可用的最新 pip
版本。
預設情況下,在所有平臺上都會安裝命令 pipX
和 pipX.Y
(其中 X.Y 代表 Python 安裝的版本),以及 pip
Python 包及其依賴項。在 Windows 和所有平臺上的虛擬環境中,也會安裝未版本化的 pip
命令。在其他平臺上,系統範圍內的未版本化 pip
命令通常指單獨安裝的 Python 2 版本。
pyvenv
命令列工具和 venv
模組利用 ensurepip
模組使 pip
在虛擬環境中隨時可用。使用命令列工具時,pip
預設安裝,而使用 venv
模組 API 時,必須顯式請求安裝 pip
。
對於 POSIX 系統上的 CPython 原始碼構建,make install
和 make altinstall
命令預設引導 pip
。此行為可以透過配置選項控制,並透過 Makefile 選項覆蓋。
在 Windows 和 Mac OS X 上,CPython 安裝程式現在預設安裝 pip
和 CPython 本身(使用者可以在安裝過程中選擇不安裝)。Windows 使用者需要選擇自動 PATH
修改才能預設在命令列中提供 pip
,否則仍然可以透過 Windows Python 啟動器作為 py -m pip
訪問它。
如 PEP 中討論的,平臺打包者可以選擇預設不安裝這些命令,只要在呼叫時,它們提供關於如何在該平臺上安裝它們的清晰簡單的說明(通常使用系統包管理器)。
備註
為了避免並行 Python 2 和 Python 3 安裝之間的衝突,當直接呼叫 ensurepip
時,預設只引導版本化的 pip3
和 pip3.4
命令——需要 --default-pip
選項才能同時請求未版本化的 pip
命令。pyvenv
和 Windows 安裝程式確保在這些環境中提供非限定的 pip
命令,並且始終可以透過 -m
開關而不是直接呼叫 pip
,以避免在具有多個 Python 安裝的系統上出現歧義。
文件變更¶
作為此更改的一部分,文件的安裝 Python 模組和分發 Python 模組部分已完全重新設計為簡短的入門和常見問題文件。大多數打包文件現在已移至 Python 打包管理局維護的Python 打包使用者指南以及各個專案的文件中。
然而,由於此遷移目前仍不完整,這些指南的舊版本仍然可用,例如使用 setuptools 構建 C 和 C++ 擴充套件和使用 setuptools 構建 C 和 C++ 擴充套件。
參見
- PEP 453 – Python 安裝中 pip 的顯式引導
PEP 由 Donald Stufft 和 Nick Coghlan 撰寫,由 Donald Stufft、Nick Coghlan、Martin von Löwis 和 Ned Deily 實現。
PEP 446:新建立的檔案描述符不可繼承¶
PEP 446 使新建立的檔案描述符不可繼承。一般來說,這是應用程式希望的行為:當啟動一個新程序時,當前開啟的檔案在新程序中也開啟可能導致各種難以發現的錯誤,並可能導致安全問題。
但是,有時需要繼承。為了支援這些情況,提供了以下新函式和方法
參見
- PEP 446 – 使新建立的檔案描述符不可繼承
PEP 由 Victor Stinner 撰寫和實現。
編解碼器處理的改進¶
自首次引入以來,codecs
模組一直旨在作為型別中立的動態編碼和解碼系統執行。然而,它與 Python 文字模型的緊密耦合,特別是內建的 str
、bytes
和 bytearray
型別的型別受限便利方法,歷史上掩蓋了這一事實。
作為澄清情況的關鍵一步,codecs.encode()
和 codecs.decode()
便利函式現在在 Python 2.7、3.3 和 3.4 中得到了正確記錄。這些函式自 Python 2.4 以來就存在於 codecs
模組中(並已包含在迴歸測試套件中),但以前只能透過執行時自省發現。
與 str
、bytes
和 bytearray
上的便利方法不同,codecs
便利函式在 Python 2 和 Python 3 中都支援任意編解碼器,而不是侷限於 Unicode 文字編碼(在 Python 3 中)或 basestring
<-> basestring
轉換(在 Python 2 中)。
在 Python 3.4 中,直譯器能夠識別標準庫中提供的已知非文字編碼,並在適當的時候引導使用者使用這些通用便利函式
>>> b"abcdef".decode("hex")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
LookupError: 'hex' is not a text encoding; use codecs.decode() to handle arbitrary codecs
>>> "hello".encode("rot13")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
LookupError: 'rot13' is not a text encoding; use codecs.encode() to handle arbitrary codecs
>>> open("foo.txt", encoding="hex")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
LookupError: 'hex' is not a text encoding; use codecs.open() to handle arbitrary codecs
在相關的更改中,只要在不破壞向後相容性的情況下可行,編碼和解碼操作期間引發的異常將被包裝在相同型別的鏈式異常中,並提及導致錯誤的編解碼器名稱
>>> import codecs
>>> codecs.decode(b"abcdefgh", "hex")
Traceback (most recent call last):
File "/usr/lib/python3.4/encodings/hex_codec.py", line 20, in hex_decode
return (binascii.a2b_hex(input), len(input))
binascii.Error: Non-hexadecimal digit found
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
binascii.Error: decoding with 'hex' codec failed (Error: Non-hexadecimal digit found)
>>> codecs.encode("hello", "bz2")
Traceback (most recent call last):
File "/usr/lib/python3.4/encodings/bz2_codec.py", line 17, in bz2_encode
return (bz2.compress(input), len(input))
File "/usr/lib/python3.4/bz2.py", line 498, in compress
return comp.compress(data) + comp.flush()
TypeError: 'str' does not support the buffer interface
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: encoding with 'bz2' codec failed (TypeError: 'str' does not support the buffer interface)
最後,如以上示例所示,這些改進使得能夠恢復非 Unicode 編解碼器的便利別名,這些別名本身已在 Python 3.2 中恢復。這意味著現在可以將二進位制資料編碼和解碼為其十六進位制表示形式(例如)寫成
>>> from codecs import encode, decode
>>> encode(b"hello", "hex")
b'68656c6c6f'
>>> decode(b"68656c6c6f", "hex")
b'hello'
標準庫中提供的二進位制和文字轉換詳見二進位制轉換和文字轉換。
(由 Nick Coghlan 貢獻,分別在 bpo-7475、bpo-17827、bpo-17828 和 bpo-19619 中。)
PEP 451:匯入系統的 ModuleSpec 型別¶
PEP 451 提供了一個封裝模組資訊的功能,匯入機制將使用這些資訊來載入模組(即模組規範)。這有助於簡化匯入實現和幾個與匯入相關的 API。此更改也是未來幾個與匯入相關的改進的墊腳石。
PEP 中面向公眾的更改完全向後相容。此外,除了匯入器作者之外,所有人都應該透明地處理這些更改。主要的查詢器和載入器方法已被棄用,但它們將繼續工作。新的匯入器應該使用 PEP 中描述的新方法。現有的匯入器應該更新以實現新方法。有關應替換的方法及其替換方法的列表,請參閱棄用部分。
其他語言更改¶
對核心 Python 語言做了一些較小的更改
Unicode 資料庫已更新至 UCD 6.3 版本。
min()
和max()
現在接受一個 *default* 僅關鍵字引數,該引數可用於指定如果它們正在評估的可迭代物件沒有元素時它們返回的值。(由 Julian Berman 在 bpo-18111 中貢獻。)模組物件現在是弱可引用的。
模組
__file__
屬性(及相關值)現在預設應始終包含絕對路徑,唯一的例外是當指令碼使用相對路徑直接執行時__main__.__file__
。(由 Brett Cannon 在 bpo-18416 中貢獻。)所有 UTF-* 編解碼器(UTF-7 除外)現在在編碼和解碼期間都拒絕代理,除非使用
surrogatepass
錯誤處理程式,但 UTF-16 解碼器(它接受有效的代理對)和 UTF-16 編碼器(它在編碼非 BMP 字元時生成它們)除外。(由 Victor Stinner、Kang-Hao (Kenny) Lu 和 Serhiy Storchaka 在 bpo-12892 中貢獻。)新的德語 EBCDIC 編解碼器
cp273
。(由 Michael Bierenfeld 和 Andrew Kuchling 在 bpo-1097797 中貢獻。)bytes
.join() 和bytearray
.join() 現在接受任意緩衝區物件作為引數。(由 Antoine Pitrou 在 bpo-15958 中貢獻。)int
建構函式現在接受任何在其 *base* 引數中具有__index__
方法的物件。(由 Mark Dickinson 在 bpo-16772 中貢獻。)幀物件現在有一個
clear()
方法,該方法清除幀中對區域性變數的所有引用。(由 Antoine Pitrou 在 bpo-17934 中貢獻。)memoryview
現在註冊為Sequence
,並支援reversed()
內建函式。(由 Nick Coghlan 和 Claudiu Popa 在 bpo-18690 和 bpo-19078 中貢獻。)由於引入了 Argument Clinic 以及對
inspect
和pydoc
模組的其他更改,help()
報告的簽名在幾種情況下已進行了修改和改進。__length_hint__()
現在是正式語言規範的一部分(請參閱 PEP 424)。 (由 Armin Ronacher 在 bpo-16148 中貢獻。)
新模組¶
asyncio¶
新的 asyncio
模組(在 PEP 3156 中定義)提供了一個標準的、可插拔的 Python 事件迴圈模型,在標準庫中提供了堅實的非同步 I/O 支援,並使其他事件迴圈實現更容易與標準庫和彼此進行互操作。
對於 Python 3.4,此模組被視為臨時 API。
參見
- PEP 3156 – 非同步 IO 支援重啟:“asyncio” 模組
PEP 由 Guido van Rossum 撰寫並領導實現。
確保安裝pip¶
新的 ensurepip
模組是 PEP 453 實現的主要基礎設施。在正常情況下,終端使用者無需與此模組互動,但如果拒絕自動引導到安裝或虛擬環境,則可以使用它手動引導 pip
。
ensurepip
包含一個捆綁的 pip
副本,該副本與附帶它的 CPython 版本的第一個釋出候選版本同步(這適用於維護版本和功能版本)。ensurepip
不訪問網際網路。如果安裝具有網際網路訪問許可權,則在執行 ensurepip
後,可以使用捆綁的 pip
將 pip
升級到比捆綁版本更新的版本。(請注意,此升級版本的 pip
被視為單獨安裝的包,如果解除安裝 Python,則不會被刪除。)
該模組命名為 *ensure*pip,因為如果在已安裝 pip
的情況下呼叫它,它將不執行任何操作。它還具有一個 --upgrade
選項,該選項將在現有已安裝的 pip
版本早於捆綁副本時安裝捆綁的 pip
副本。
enum¶
新的 enum
模組(在 PEP 435 中定義)提供了列舉型別的標準實現,允許其他模組(如 socket
)透過將不透明的整數常量替換為向後相容的列舉值來提供更具資訊量的錯誤訊息和更好的除錯支援。
參見
- PEP 435 – 向 Python 標準庫新增 Enum 型別
PEP 由 Barry Warsaw、Eli Bendersky 和 Ethan Furman 撰寫,由 Ethan Furman 實現。
pathlib¶
新的 pathlib
模組提供了表示檔案系統路徑的類,這些路徑具有適用於不同作業系統的語義。路徑類分為 *純路徑*,它們提供純計算操作而不涉及 I/O,以及 *具體路徑*,它們繼承自純路徑但也提供 I/O 操作。
對於 Python 3.4,此模組被視為臨時 API。
參見
- PEP 428 – pathlib 模組 – 面向物件的檔案系統路徑
PEP 由 Antoine Pitrou 撰寫和實現。
選擇器¶
新的 selectors
模組(作為實現 PEP 3156 的一部分建立)允許高效的高階 I/O 複用,基於 select
模組原語構建。
statistics¶
新的 statistics
模組(在 PEP 450 中定義)直接在標準庫中提供了一些核心統計功能。此模組支援計算資料系列的均值、中位數、眾數、方差和標準差。
參見
- PEP 450 – 向標準庫新增統計模組
PEP 由 Steven D’Aprano 撰寫和實現
tracemalloc¶
新的 tracemalloc
模組(在 PEP 454 中定義)是一個除錯工具,用於跟蹤 Python 分配的記憶體塊。它提供以下資訊
跟蹤物件的分配位置
按檔名和行號統計已分配記憶體塊:總大小、已分配記憶體塊的數量和平均大小
計算兩個快照之間的差異以檢測記憶體洩漏
參見
- PEP 454 – 新增一個新的 tracemalloc 模組以跟蹤 Python 記憶體分配
PEP 由 Victor Stinner 撰寫和實現
改進的模組¶
abc¶
新函式 abc.get_cache_token()
可用於瞭解何時使受物件圖更改影響的快取失效。(由 Łukasz Langa 在 bpo-16832 中貢獻。)
新類 ABC
具有 ABCMeta
作為其元類。使用 ABC
作為基類與指定 metaclass=abc.ABCMeta
的效果基本相同,但鍵入更簡單,閱讀更容易。(由 Bruno Dupuis 在 bpo-16049 中貢獻。)
aifc¶
getparams()
方法現在返回一個命名元組而不是普通元組。(由 Claudiu Popa 在 bpo-17818 中貢獻。)
aifc.open()
現在支援上下文管理協議:當在 with
塊中使用時,返回物件的 close()
方法將在塊結束時自動呼叫。(由 Serhiy Storchacha 在 bpo-16486 中貢獻。)
writeframesraw()
和 writeframes()
方法現在接受任何類位元組物件。(由 Serhiy Storchaka 在 bpo-8311 中貢獻。)
argparse¶
FileType
類現在接受 *encoding* 和 *errors* 引數,這些引數將傳遞給 open()
。(由 Lucas Maystre 在 bpo-11175 中貢獻。)
音訊操作¶
audioop
現在支援 24 位取樣。(由 Serhiy Storchaka 在 bpo-12866 中貢獻。)
新的 byteswap()
函式將大端序樣本轉換為小端序,反之亦然。(由 Serhiy Storchaka 在 bpo-19641 中貢獻。)
所有 audioop
函式現在都接受任何類位元組物件。不接受字串:它們以前不起作用,現在它們會立即引發錯誤。(由 Serhiy Storchaka 在 bpo-16685 中貢獻。)
base64¶
base64
中的編碼和解碼函式現在接受任何類位元組物件,而以前它要求 bytes
或 bytearray
例項。(由 Nick Coghlan 在 bpo-17839 中貢獻。)
新函式 a85encode()
、a85decode()
、b85encode()
和 b85decode()
提供了將二進位制資料編碼和解碼為 Ascii85
和 git/mercurial Base85
格式的功能。 a85
函式具有可用於使其與 Ascii85
編碼變體相容的選項,包括 Adobe 變體。(由 Martin Morrison、Mercurial 專案、Serhiy Storchaka 和 Antoine Pitrou 在 bpo-17618 中貢獻。)
collections¶
ChainMap.new_child()
方法現在接受一個 *m* 引數,用於指定要新增到鏈中的子對映。這允許將現有對映和/或自定義對映型別用於子級。(由 Vinay Sajip 在 bpo-16613 中貢獻。)
顏色系統¶
RGB — YIQ 轉換的係數中的數字位數已擴充套件,以使其與 FCC NTSC 版本匹配。結果變化應小於 1%,並且可能更好地匹配其他地方找到的結果。(由 Brian Landers 和 Serhiy Storchaka 在 bpo-14323 中貢獻。)
contextlib¶
新的 contextlib.suppress
上下文管理器有助於澄清故意抑制單個語句中的異常的程式碼意圖。(由 Raymond Hettinger 在 bpo-15806 和 Zero Piraeus 在 bpo-19266 中貢獻。)
新的 contextlib.redirect_stdout()
上下文管理器使實用程式指令碼更容易處理將輸出寫入 sys.stdout
且不提供任何重定向選項的僵硬 API。使用上下文管理器,sys.stdout
輸出可以重定向到任何其他流,或者結合 io.StringIO
,重定向到字串。後者尤其有用,例如,用於捕獲旨在實現命令列介面的函式的輸出。它僅建議用於實用程式指令碼,因為它會影響 sys.stdout
的全域性狀態。(由 Raymond Hettinger 在 bpo-15805 中貢獻。)
contextlib
文件也已更新,以包含關於單次使用、可重用和可重入上下文管理器之間差異的討論。
dbm¶
dbm.open()
物件現在支援上下文管理協議。當在 with
語句中使用時,資料庫物件的 close
方法將在塊結束時自動呼叫。(由 Claudiu Popa 和 Nick Coghlan 在 bpo-19282 中貢獻。)
dis¶
函式 show_code()
、dis()
、distb()
和 disassemble()
現在接受一個僅關鍵字 *file* 引數,該引數控制它們將輸出寫入何處。
dis
模組現在圍繞 Instruction
類構建,該類提供對每個單獨位元組碼操作的詳細資訊的面向物件訪問。
一個新方法 get_instructions()
提供了一個迭代器,該迭代器為給定的 Python 程式碼片段發出指令流。因此,現在可以編寫一個程式,以不同於 dis
模組本身提供的方式檢查和操作位元組碼物件。例如
>>> import dis
>>> for instr in dis.get_instructions(lambda x: x + 1):
... print(instr.opname)
LOAD_FAST
LOAD_CONST
BINARY_ADD
RETURN_VALUE
dis
模組中的各種顯示工具已重寫以使用這些新元件。
此外,一個新的對應用程式友好的類 Bytecode
提供了一個面向物件的 API,用於以人類可讀的形式檢查位元組碼以及迭代指令。Bytecode
建構函式接受與 get_instructions()
相同的引數(加上一個可選的 *current_offset*),並且生成的結果物件可以迭代以生成 Instruction
物件。但它也有一個 dis
方法,等同於在建構函式引數上呼叫 dis
,但作為多行字串返回
>>> bytecode = dis.Bytecode(lambda x: x + 1, current_offset=3)
>>> for instr in bytecode:
... print('{} ({})'.format(instr.opname, instr.opcode))
LOAD_FAST (124)
LOAD_CONST (100)
BINARY_ADD (23)
RETURN_VALUE (83)
>>> bytecode.dis().splitlines()
[' 1 0 LOAD_FAST 0 (x)',
' --> 3 LOAD_CONST 1 (1)',
' 6 BINARY_ADD',
' 7 RETURN_VALUE']
Bytecode
還有一個類方法 from_traceback()
,它提供了操作回溯的能力(即 print(Bytecode.from_traceback(tb).dis())
等同於 distb(tb)
)。
(由 Nick Coghlan、Ryan Kelly 和 Thomas Kluyver 在 bpo-11816 中以及 Claudiu Popa 在 bpo-17916 中貢獻。)
新函式 stack_effect()
計算給定操作碼和引數對 Python 堆疊的影響,這些資訊在其他地方不可用。(由 Larry Hastings 在 bpo-19722 中貢獻。)
doctest¶
一個新的 選項標誌 FAIL_FAST
,一旦檢測到第一個失敗,就會停止測試執行。(由 R. David Murray 和 Daniel Urban 在 bpo-16522 中貢獻。)
doctest
命令列介面現在使用 argparse
,並且有兩個新選項,-o
和 -f
。-o
允許在命令列上指定 doctest 選項,而 -f
是 -o FAIL_FAST
的簡寫(以並行 unittest
CLI 支援的類似選項)。(由 R. David Murray 在 bpo-11390 中貢獻。)
doctest
現在將在擴充套件模組 __doc__
字串中查詢 doctests。(由 Zachary Ware 在 bpo-3158 中貢獻。)
email¶
as_string()
現在接受一個 *policy* 引數,用於在生成訊息的字串表示時覆蓋訊息的預設策略。這意味著 as_string
現在可以在更多情況下使用,而不必建立和使用 generator
來將其格式化引數傳遞給其 flatten
方法。(由 R. David Murray 在 bpo-18600 中貢獻。)
添加了新方法 as_bytes()
,用於生成訊息的位元組表示,其方式類似於 as_string
生成字串表示。它不接受 *maxheaderlen* 引數,但接受 *unixfrom* 和 *policy* 引數。Message
__bytes__()
方法呼叫它,這意味著 bytes(mymsg)
現在將產生直觀的結果:一個包含完整格式化訊息的位元組物件。(由 R. David Murray 在 bpo-18600 中貢獻。)
Message.set_param()
方法現在接受一個 *replace* 關鍵字引數。指定時,關聯的頭部將被更新,而不會更改其在頭部列表中的位置。為了向後相容性,預設值為 False
。(由 R. David Murray 在 bpo-18891 中貢獻。)
Message
的兩個新子類(EmailMessage
和 MIMEPart
)以及一個新的子模組 contentmanager
和一個新的 policy
屬性 content_manager
已新增。所有文件目前都在新模組中,該模組作為電子郵件新臨時 API的一部分新增。這些類提供了許多新方法,使從電子郵件訊息中提取內容和向其中插入內容變得更加容易。有關詳細資訊,請參閱 contentmanager
文件和 email: 示例。這些 API 新增完成了電子郵件 6 專案計劃的大部分工作。目前臨時 API 計劃在 Python 3.5 中最終確定(可能在錯誤處理領域有一些小的新增)。(由 R. David Murray 在 bpo-18891 中貢獻。)
檔案比較¶
新函式 clear_cache()
提供了清除 filecmp
比較快取的功能,該快取使用 os.stat()
資訊來確定檔案自上次比較以來是否已更改。例如,如果檔案可能在位元定檔案系統的檔案修改時間欄位解析度更短的時間內被更改並重新檢查,則可以使用此功能。(由 Mark Levitt 在 bpo-18149 中貢獻。)
新的模組屬性 DEFAULT_IGNORES
提供了目錄列表,用作 dircmp()
函式的 *ignore* 引數的預設值。(由 Eli Bendersky 在 bpo-15442 中貢獻。)
functools¶
新的 partialmethod()
描述符為描述符帶來了部分引數應用,就像 partial()
為普通可呼叫物件提供的那樣。新的描述符還使任意可呼叫物件(包括 partial()
例項)在包含在類定義中時更容易表現得像普通例項方法。(由 Alon Horev 和 Nick Coghlan 在 bpo-4331 中貢獻。)
新的 singledispatch()
裝飾器為 Python 標準庫帶來了對單分派泛型函式的支援。面向物件程式設計側重於將對一組共同資料的多個操作分組到一個類中,而泛型函式則側重於將一個操作的多個實現分組,使其能夠與*不同*型別的資料一起工作。
參見
- PEP 443 – 單分派泛型函式
PEP 由 Łukasz Langa 撰寫和實現。
total_ordering()
現在支援底層比較函式返回 NotImplemented
。(由 Katie Miller 在 bpo-10042 中貢獻。)
partial()
函式的純 Python 版本現在已在 stdlib 中;在 CPython 中,它被 C 加速版本覆蓋,但可供其他實現使用。(由 Brian Thorne 在 bpo-12428 中貢獻。)
gc¶
新函式 get_stats()
返回一個包含三個按代劃分的字典的列表,其中包含直譯器啟動以來的垃圾回收統計資訊。(由 Antoine Pitrou 在 bpo-16351 中貢獻。)
glob¶
新函式 escape()
提供了一種轉義檔名中特殊字元的方法,使它們不會成為 globbing 擴充套件的一部分,而是按字面值匹配。(由 Serhiy Storchaka 在 bpo-8402 中貢獻。)
hashlib¶
新函式 hashlib.pbkdf2_hmac()
提供了 PKCS#5 基於密碼的金鑰派生函式 2。(由 Christian Heimes 在 bpo-18582 中貢獻。)
hashlib
雜湊物件的 name
屬性現在是一個正式支援的介面。它在 CPython 的 hashlib
中一直存在(儘管它並未對所有支援的雜湊返回小寫名稱),但它不是公共介面,因此一些其他 Python 實現以前不支援它。(由 Jason R. Coombs 在 bpo-18532 中貢獻。)
hmac¶
hmac
現在接受 bytearray
和 bytes
作為 new()
函式的 key 引數,並且 new()
函式和 update()
方法的 msg 引數現在接受 hashlib
模組支援的任何型別。(由 Jonas Borgström 在 bpo-18240 中貢獻。)
hmac.new()
函式的 digestmod 引數現在可以是 hashlib
識別的任何雜湊摘要名稱。此外,目前 digestmod 預設值為 MD5
的行為已被棄用:在未來的 Python 版本中將不再有預設值。(由 Christian Heimes 在 bpo-17276 中貢獻。)
透過新增 block_size
和 name
屬性(以及對 digest_size
屬性的正式文件),hmac
模組現在完全符合 PEP 247 API。(由 Christian Heimes 在 bpo-18775 中貢獻。)
html¶
新函式 unescape()
函式將 HTML5 字元引用轉換為相應的 Unicode 字元。(由 Ezio Melotti 在 bpo-2927 中貢獻。)
HTMLParser
接受一個新的關鍵字引數 convert_charrefs,當它為 True
時,會自動轉換所有字元引用。為了向後相容,它的預設值為 False
,但在未來的 Python 版本中將變為 True
,因此建議您顯式設定它並更新您的程式碼以使用此新功能。(由 Ezio Melotti 在 bpo-13633 中貢獻。)
HTMLParser
的 strict 引數現已棄用。(由 Ezio Melotti 在 bpo-15114 中貢獻。)
http¶
send_error()
現在接受一個可選的附加 explain 引數,可用於提供擴充套件錯誤描述,覆蓋硬編碼的預設值(如果存在)。此擴充套件錯誤描述將使用 error_message_format
屬性進行格式化,並作為錯誤響應的正文傳送。(由 Karl Cow 在 bpo-12921 中貢獻。)
http.server
命令列介面 現在有一個 -b/--bind
選項,使伺服器監聽特定地址。(由 Malte Swart 在 bpo-17764 中貢獻。)
idlelib 和 IDLE¶
由於 idlelib 實現了 IDLE shell 和編輯器,並且不打算被其他程式匯入,因此它在每個版本中都得到了改進。有關自 3.3.0 以來的累計更改以及未來 3.4.x 版本中的更改,請參閱 Lib/idlelib/NEWS.txt
。此檔案也可透過 IDLE 對話方塊獲取。
importlib¶
InspectLoader
抽象基類定義了一個新方法 source_to_code()
,它接受源資料和路徑,並返回一個程式碼物件。預設實現等同於 compile(data, path, 'exec', dont_inherit=True)
。(由 Eric Snow 和 Brett Cannon 在 bpo-15627 中貢獻。)
InspectLoader
現在也為 get_code()
方法提供了預設實現。然而,出於效能原因,通常希望覆蓋預設實現。(由 Brett Cannon 在 bpo-18072 中貢獻。)
reload()
函式已從 imp
移至 importlib
,作為 imp
模組棄用的一部分。(由 Berker Peksag 在 bpo-18193 中貢獻。)
importlib.util
現在有一個 MAGIC_NUMBER
屬性,提供對位元組碼版本號的訪問。這取代了已棄用的 imp
模組中的 get_magic()
函式。(由 Brett Cannon 在 bpo-18192 中貢獻。)
新的 importlib.util
函式 cache_from_source()
和 source_from_cache()
取代了已棄用的 imp
模組中同名的函式。(由 Brett Cannon 在 bpo-18194 中貢獻。)
importlib
載入程式 NamespaceLoader
現在符合 InspectLoader
抽象基類,這意味著 runpy
和 python -m
現在可以與名稱空間包一起使用。(由 Brett Cannon 在 bpo-18058 中貢獻。)
importlib.util
有一個新函式 decode_source()
,它使用通用換行符處理從位元組解碼源。這對於實現 InspectLoader.get_source()
方法很有用。
importlib.machinery.ExtensionFileLoader
現在有一個 get_filename()
方法。這在最初的實現中被無意中省略了。(由 Eric Snow 在 bpo-19152 中貢獻。)
inspect¶
inspect
模組現在提供了一個基本的 命令列介面,可以快速顯示模組、類和函式的原始碼及其他資訊。(由 Claudiu Popa 和 Nick Coghlan 在 bpo-18626 中貢獻。)
unwrap()
使解開由 functools.wraps()
(以及任何其他在包裝函式上設定 __wrapped__
屬性的 API)建立的包裝函式鏈變得容易。(由 Daniel Urban、Aaron Iles 和 Nick Coghlan 在 bpo-13266 中貢獻。)
作為新的 enum
模組實現的一部分,inspect
模組現在對自定義 __dir__
方法和透過元類提供的動態類屬性提供了更好的支援。(由 Ethan Furman 在 bpo-18929 和 bpo-19030 中貢獻。)
getfullargspec()
和 getargspec()
現在使用 signature()
API。這使它們能夠支援更廣泛的可呼叫物件,包括具有 __signature__
屬性的物件、具有引數 clinic 提供的元資料的物件、functools.partial()
物件等。請注意,與 signature()
不同,這些函式仍然忽略 __wrapped__
屬性,並報告已繫結方法的已繫結的第一個引數,因此如果需要這些功能,仍然需要更新您的程式碼以直接使用 signature()
。(由 Yury Selivanov 在 bpo-17481 中貢獻。)
signature()
現在支援 CPython 函式的鴨子型別,這增加了對用 Cython 編譯的函式的支援。(由 Stefan Behnel 和 Yury Selivanov 在 bpo-17159 中貢獻。)
ipaddress¶
ipaddress
在 Python 3.3 中作為 臨時 API 新增到標準庫中。隨著 Python 3.4 的釋出,此限定已被移除:ipaddress
現在被視為穩定 API,受正常標準庫維護向後相容性的要求約束。
一個新的 is_global
屬性,如果地址是全域性可路由的,則為 True
。(由 Peter Moody 在 bpo-17400 中貢獻。)
logging¶
TimedRotatingFileHandler
有一個新的 atTime 引數,可用於指定輪換髮生的時間。(由 Ronald Oussoren 在 bpo-9556 中貢獻。)
SocketHandler
和 DatagramHandler
現在支援 Unix 域套接字(透過將 port 設定為 None
)。(由 Vinay Sajip 在 commit ce46195b56a9 中貢獻。)
fileConfig()
現在接受 configparser.RawConfigParser
子類例項作為 fname 引數。這有助於在使用配置檔案時,日誌配置只是整個應用程式配置的一部分,或者應用程式在將配置傳遞給 fileConfig()
之前對其進行了修改。(由 Vinay Sajip 在 bpo-16110 中貢獻。)
現在可以從透過 logging.config.listen()
函式接收到的套接字日誌配置資料,透過提供驗證函式作為新的 verify 關鍵字引數的引數,在處理之前進行驗證。(由 Vinay Sajip 在 bpo-15452 中貢獻。)
marshal¶
預設的 marshal
版本已升級到 3。實現新版本的程式碼恢復了 Python2 的行為,即只記錄 interned 字串的一個副本並在反序列化時保留 interning,並將此“一個副本”功能擴充套件到任何物件型別(包括處理遞迴引用)。這減少了 .pyc
檔案的大小以及從 .pyc
(或 .pyo
)檔案載入模組時模組在記憶體中佔用的記憶體量。(由 Kristján Valur Jónsson 在 bpo-16475 中貢獻,Antoine Pitrou 在 bpo-19219 中提供了額外的速度提升。)
mmap¶
multiprocessing¶
在 Unix 上,使用 multiprocessing
啟動程序時,增加了兩個新的 啟動方法:spawn
和 forkserver
。這些方法使程序與執行緒的混合更加健壯,並且 spawn
方法與 multiprocessing 在 Windows 上一直使用的語義相匹配。新函式 get_all_start_methods()
報告平臺上所有可用的啟動方法,get_start_method()
報告當前啟動方法,set_start_method()
設定啟動方法。(由 Richard Oudkerk 在 bpo-8713 中貢獻。)
multiprocessing
現在也有了 context
的概念,它決定了子程序的建立方式。新函式 get_context()
返回使用指定啟動方法的上下文。它具有與 multiprocessing
模組本身相同的 API,因此您可以使用它來建立 Pool
和其他在該上下文下操作的物件。這允許框架和應用程式或同一應用程式的不同部分使用多程序而不相互干擾。(由 Richard Oudkerk 在 bpo-18999 中貢獻。)
除了使用舊的 *fork* 啟動方法外,子程序不再繼承父程序不必要的控制代碼/檔案描述符(bpo-8713 的一部分)。
multiprocessing
現在依賴於 runpy
(它實現了 -m
開關)在使用 spawn
或 forkserver
啟動方法時,在子程序中適當地初始化 __main__
。這解決了將多程序、-m
命令列開關和顯式相對匯入結合使用時,在子程序中可能導致某些模糊失敗的邊緣情況。(由 Nick Coghlan 在 bpo-19946 中貢獻。)
operator¶
新函式 length_hint()
提供了關於如何使用 __length_hint__()
特殊方法的規範的實現,作為 PEP 424 語言特徵的正式規範的一部分。(由 Armin Ronacher 在 bpo-16148 中貢獻。)
現在有一個 operator
模組的純 Python 版本,可供參考和供 Python 的其他實現使用。(由 Zachary Ware 在 bpo-16694 中貢獻。)
os¶
有一些新函式可以獲取和設定檔案描述符(os.get_inheritable()
, os.set_inheritable()
)或 Windows 控制代碼(os.get_handle_inheritable()
, os.set_handle_inheritable()
)的 可繼承標誌。
新函式 cpu_count()
報告 Python 執行平臺上可用的 CPU 數量(如果無法確定數量,則為 None
)。multiprocessing.cpu_count()
函式現在是基於此函式實現的)。(由 Trent Nelson、Yogesh Chaudhari、Victor Stinner 和 Charles-François Natali 在 bpo-17914 中貢獻。)
os.path.samestat()
現在在 Windows 平臺上可用(並且 os.path.samefile()
實現現在在 Unix 和 Windows 之間共享)。(由 Brian Curtin 在 bpo-11939 中貢獻。)
os.path.ismount()
現在可以識別 Windows 上掛載在驅動器根目錄下的卷。(由 Tim Golden 在 bpo-9035 中貢獻。)
os.open()
支援兩個新的標誌,如果平臺提供它們:O_PATH
(未開啟的檔案描述符)和 O_TMPFILE
(無名臨時檔案;截至 3.4.0 版本,僅在 Linux 核心版本 3.11 或更高且具有 uapi 標頭檔案的系統上可用)。(由 Christian Heimes 在 bpo-18673 中以及 Benjamin Peterson 貢獻。)
pdb¶
pdb
已增強,以更有用的方式處理生成器、yield
和 yield from
。這在除錯基於 asyncio
的程式時特別有用。(由 Andrew Svetlov 和 Xavier de Gaye 在 bpo-16596 中貢獻。)
pdb
中的 print
命令已被移除,恢復了從 pdb 命令列訪問 Python print()
函式的功能。Python2 的 pdb
沒有 print
命令;相反,輸入 print
會執行 print
語句。在 Python3 中,print
錯誤地成為了 pdb p
命令的別名。p
列印其引數的 repr
,而不是像 Python2 的 print
命令那樣列印 str
。更糟糕的是,Python3 的 pdb print
命令遮蔽了 Python3 的 print
函式,使其在 pdb
提示符下無法訪問。(由 Connor Osborn 在 bpo-18764 中貢獻。)
pickle¶
pickle
現在支援(但預設不使用)新的 pickle 協議,協議 4。此新協議解決了以前協議中存在的許多問題,例如巢狀類、非常大的字串和容器以及其 __new__()
方法接受僅限關鍵字引數的類的序列化。它還提供了一些效率改進。
參見
- PEP 3154 – Pickle protocol 4
PEP 由 Antoine Pitrou 編寫,並由 Alexandre Vassalotti 實現。
plistlib¶
plistlib
現在具有類似於 stdlib 序列化協議標準模式的 API,具有新的 load()
、dump()
、loads()
和 dumps()
函式。(舊 API 現已棄用。)除了已支援的 XML plist 格式(FMT_XML
)之外,它現在還支援二進位制 plist 格式(FMT_BINARY
)。(由 Ronald Oussoren 等人 在 bpo-14455 中貢獻。)
poplib¶
poplib
已新增兩個新方法:capa()
,它返回 POP 伺服器釋出的 capabilities 列表;以及 stls()
,如果 POP 伺服器支援,它將明文 POP3 會話切換到加密 POP3 會話。(由 Lorenzo Catucci 在 bpo-4473 中貢獻。)
pprint¶
pprint
模組的 PrettyPrinter
類及其 pformat()
和 pprint()
函式有一個新選項 compact,它控制輸出的格式。目前,將 compact 設定為 True
意味著序列將以每行(縮排)可容納的儘可能多的序列元素列印。(由 Serhiy Storchaka 在 bpo-19132 中貢獻。)
長字串現在使用 Python 的正常行繼續語法進行換行。(由 Antoine Pitrou 在 bpo-17150 中貢獻。)
pty¶
pty.spawn()
現在返回子程序的 os.waitpid()
的狀態值,而不是 None
。(由 Gregory P. Smith 貢獻。)
pydoc¶
pydoc
模組現在直接基於 inspect.signature()
內省 API,允許它為各種可呼叫物件提供簽名信息。此更改也意味著在顯示幫助資訊時會考慮 __wrapped__
屬性。(由 Larry Hastings 在 bpo-19674 中貢獻。)
pydoc
模組不再顯示已繫結方法的 self
引數。相反,它旨在始終顯示所提供的可呼叫物件的精確當前簽名。(由 Larry Hastings 在 bpo-20710 中貢獻。)
除了對 pydoc
直接進行的更改外,由於 inspect
模組的底層更改,其對自定義 __dir__
方法和各種描述符行為的處理也得到了顯著改進。
re¶
新函式 fullmatch()
和 Pattern.fullmatch()
方法將模式錨定在字串的兩端以進行匹配。這提供了一種明確匹配目標的方法,避免了因程式碼更改或向現有正則表示式新增替代項而導致 $
字元丟失的一類細微錯誤。(由 Matthew Barnett 在 bpo-16203 中貢獻。)
正則表示式物件 的 repr 現在包含模式和標誌;匹配物件 的 repr 現在包含開始、結束和匹配的字串部分。(由 Hugo Lopes Tavares 和 Serhiy Storchaka 在 bpo-13592 和 bpo-17087 中貢獻。)
resource¶
新函式 prlimit()
,在核心版本 2.6.36 或更高、glibc 2.13 或更高的 Linux 平臺上可用,它提供了查詢或設定除呼叫程序之外的其他程序的資源限制的能力。(由 Christian Heimes 在 bpo-16595 中貢獻。)
在 Linux 核心版本 2.6.36 或更高版本上,還有一些新的 Linux 特定常量:RLIMIT_MSGQUEUE
、RLIMIT_NICE
、RLIMIT_RTPRIO
、RLIMIT_RTTIME
和 RLIMIT_SIGPENDING
。(由 Christian Heimes 在 bpo-19324 中貢獻。)
在 FreeBSD 版本 9 及更高版本上,有一些新的 FreeBSD 特定常量:RLIMIT_SBSIZE
、RLIMIT_SWAP
和 RLIMIT_NPTS
。(由 Claudiu Popa 在 bpo-19343 中貢獻。)
select¶
epoll
物件現在支援上下文管理協議。在 with
語句中使用時,close()
方法將在塊結束時自動呼叫。(由 Serhiy Storchaka 在 bpo-16488 中貢獻。)
devpoll
物件現在具有 fileno()
和 close()
方法,以及一個新屬性 closed
。(由 Victor Stinner 在 bpo-18794 中貢獻。)
shelve¶
Shelf
例項現在可以在 with
語句中使用,並在 with
塊結束時自動關閉。(由 Filip Gruszczyński 在 bpo-13896 中貢獻。)
shutil¶
copyfile()
現在在原始檔和目標檔案相同時引發一個特定的 Error
子類 SameFileError
,這允許應用程式對此特定錯誤採取適當的行動。(由 Atsuo Ishimoto 和 Hynek Schlawack 在 bpo-1492704 中貢獻。)
smtpd¶
SMTPServer
和 SMTPChannel
類現在接受一個 map 關鍵字引數,如果指定,該引數將作為其 map 引數傳遞給 asynchat.async_chat
。這允許應用程式避免影響全域性套接字對映。(由 Vinay Sajip 在 bpo-11959 中貢獻。)
smtplib¶
SMTPException
現在是 OSError
的子類,這允許在單個 try/except 語句中捕獲套接字級別錯誤和 SMTP 協議級別錯誤,對於只關心是否發生錯誤的程式碼。(由 Ned Jackson Lovely 在 bpo-2118 中貢獻。)
socket¶
socket 模組現在支援 CAN_BCM
協議,如果平臺支援它的話。(由 Brian Thorne 在 bpo-15359 中貢獻。)
Socket 物件有新的方法來獲取或設定其 可繼承標誌,即 get_inheritable()
和 set_inheritable()
。
socket.AF_*
和 socket.SOCK_*
常量現在是使用新 enum
模組的列舉值。這允許在除錯期間列印有意義的名稱,而不是整數“魔法數字”。
AF_LINK
常量現在在 BSD 和 OSX 上可用。
inet_pton()
和 inet_ntop()
現在在 Windows 上受支援。(由 Atsuo Ishimoto 在 bpo-7171 中貢獻。)
sqlite3¶
connect()
函式的一個新的布林引數 uri,可以用來指示 database 引數是一個 uri
(參見 SQLite URI 文件)。(由 poq 在 bpo-13773 中貢獻。)
ssl¶
已新增 PROTOCOL_TLSv1_1
和 PROTOCOL_TLSv1_2
(TLSv1.1 和 TLSv1.2 支援);這些協議的支援僅在 Python 連結到 OpenSSL 1.0.1 或更高版本時可用。(由 Michele Orrù 和 Antoine Pitrou 在 bpo-16692 中貢獻。)
新函式 create_default_context()
提供了一種標準方法來獲取 SSLContext
,其設定旨在在相容性和安全性之間取得合理平衡。這些設定比 SSLContext
建構函式提供的預設設定更嚴格,並且如果最佳實踐安全要求發生變化,將來可能會進行調整,而無需事先棄用。使用支援 SSL 的標準庫的新推薦最佳實踐是使用 create_default_context()
獲取 SSLContext
物件,根據需要進行修改,然後將其作為適當標準庫 API 的 context 引數傳遞。(由 Christian Heimes 在 bpo-19689 中貢獻。)
SSLContext
方法 load_verify_locations()
接受一個新的可選引數 cadata,可用於分別透過字串或位元組直接提供 PEM 或 DER 編碼的證書。(由 Christian Heimes 在 bpo-18138 中貢獻。)
新函式 get_default_verify_paths()
返回一個命名元組,包含 set_default_verify_paths()
方法用於設定 OpenSSL 預設 cafile
和 capath
的路徑和環境變數。這有助於除錯預設驗證問題。(由 Christian Heimes 在 bpo-18143 中貢獻。)
SSLContext
有一個新的方法 cert_store_stats()
,它報告已載入的 X.509
證書、X.509 CA
證書和證書吊銷列表(crl
s)的數量,以及一個 get_ca_certs()
方法,該方法返回已載入的 CA
證書列表。(由 Christian Heimes 在 bpo-18147 中貢獻。)
如果 OpenSSL 0.9.8 或更高版本可用,SSLContext
將有一個新屬性 verify_flags
,透過將其設定為新常量 VERIFY_DEFAULT
、VERIFY_CRL_CHECK_LEAF
、VERIFY_CRL_CHECK_CHAIN
或 VERIFY_X509_STRICT
的某種組合,可以控制證書驗證過程。OpenSSL 預設不進行任何 CRL 驗證。(由 Christien Heimes 在 bpo-8813 中貢獻。)
新的 SSLContext
方法 load_default_certs()
從預設位置載入一組預設的“證書頒發機構”(CA)證書,這些位置因平臺而異。它可用於載入 TLS Web 伺服器身份驗證證書(purpose=
SERVER_AUTH
),供客戶端用於驗證伺服器,以及伺服器用於驗證客戶端證書的證書(purpose=
CLIENT_AUTH
)。(由 Christian Heimes 在 bpo-19292 中貢獻。)
兩個新的僅限 Windows 的函式 enum_certificates()
和 enum_crls()
提供了從 Windows 證書儲存區檢索證書、證書資訊和 CRLs 的能力。(由 Christian Heimes 在 bpo-17134 中貢獻。)
使用新的 ssl.SSLContext.set_servername_callback()
方法支援伺服器端 SNI(伺服器名稱指示)。(由 Daniel Black 在 bpo-8109 中貢獻。)
SSLSocket.getpeercert()
返回的字典包含額外的 X509v3
擴充套件項:crlDistributionPoints
、calIssuers
和 OCSP
URIs。(由 Christian Heimes 在 bpo-18379 中貢獻。)
stat¶
stat
模組現在由 _stat
中的 C 實現支援。由於大多數值未標準化且與平臺相關,因此需要 C 實現。(由 Christian Heimes 在 bpo-11016 中貢獻。)
該模組支援新的 ST_MODE
標誌:S_IFDOOR
、S_IFPORT
和 S_IFWHT
。(由 Christian Hiemes 在 bpo-11016 中貢獻。)
struct¶
新函式 iter_unpack
和編譯格式上的新方法 struct.Struct.iter_unpack()
提供了對包含給定資料格式重複例項的緩衝區的流式解包。(由 Antoine Pitrou 在 bpo-17804 中貢獻。)
subprocess¶
check_output()
現在接受一個 input 引數,可用於為執行的命令提供 stdin
的內容。(由 Zack Weinberg 在 bpo-16624 中貢獻。)
getoutput()
和 getstatusoutput()
現在在 Windows 上工作。此更改實際上是在 3.3.4 中無意中進行的。(由 Tim Golden 在 bpo-10197 中貢獻。)
sunau¶
getparams()
方法現在返回一個命名元組而不是普通元組。(由 Claudiu Popa 在 bpo-18901 中貢獻。)
sunau.open()
現在支援上下文管理協議:當在 with
塊中使用時,返回物件的 close
方法將在塊結束時自動呼叫。(由 Serhiy Storchaka 在 bpo-18878 中貢獻。)
AU_write.setsampwidth()
現在支援 24 位樣本,因此增加了使用模組寫入 24 位樣本的支援。(由 Serhiy Storchaka 在 bpo-19261 中貢獻。)
writeframesraw()
和 writeframes()
方法現在接受任何類位元組物件。(由 Serhiy Storchaka 在 bpo-8311 中貢獻。)
sys¶
新函式 sys.getallocatedblocks()
返回直譯器當前分配的塊數。(在 CPython 中,使用預設的 --with-pymalloc
設定,這是透過 PyObject_Malloc()
API 進行的分配。)這對於跟蹤記憶體洩漏非常有用,尤其是透過測試套件自動化跟蹤時。(由 Antoine Pitrou 在 bpo-13390 中貢獻。)
當 Python 直譯器在 互動模式 下啟動時,它會檢查 sys
模組上的 __interactivehook__
屬性。如果該屬性存在,則在互動模式啟動之前不帶任何引數呼叫其值。此檢查在讀取 PYTHONSTARTUP
檔案之後進行,因此可以在其中設定。如果平臺支援 readline
,site
模組會將其設定為一個啟用 Tab 補全和歷史記錄儲存(在 ~/.python-history
中)的函式。如果您不希望出現此(新)行為,可以在 PYTHONSTARTUP
、sitecustomize
或 usercustomize
中透過從 sys
中刪除此屬性(或將其設定為其他可呼叫物件)來覆蓋它。(由 Éric Araujo 和 Antoine Pitrou 在 bpo-5845 中貢獻。)
tarfile¶
tarfile
模組現在在直接作為指令碼呼叫或透過 -m
呼叫時支援簡單的 命令列介面。這可用於建立和提取 tarfile 歸檔。(由 Berker Peksag 在 bpo-13477 中貢獻。)
textwrap¶
TextWrapper
類有兩個新的屬性/建構函式引數:max_lines
,它限制了輸出的行數;以及 placeholder
,如果輸出因 max_lines 而被截斷,該字串將出現在輸出的末尾。在此基礎上,新增了一個便捷函式 shorten()
,它將輸入中的所有空白摺疊為單個空格,並生成一行給定 width 的文字,以 placeholder(預設為 [...]
)結尾。(由 Antoine Pitrou 和 Serhiy Storchaka 在 bpo-18585 和 bpo-18725 中貢獻。)
threading¶
代表主執行緒的 Thread
物件可以透過新的 main_thread()
函式獲取。在正常情況下,這將是 Python 直譯器啟動的執行緒。(由 Andrew Svetlov 在 bpo-18882 中貢獻。)
traceback¶
新的 traceback.clear_frames()
函式接受一個回溯物件並清除其引用的所有幀中的區域性變數,從而減少記憶體消耗。(由 Andrew Kuchling 在 bpo-1565525 中貢獻。)
types¶
一個新的 DynamicClassAttribute()
描述符提供了一種定義屬性的方法,該屬性在透過例項物件查詢時表現正常,但在透過類查詢時則路由到 class 的 __getattr__
。這允許在類上啟用屬性,並具有與類上同名的虛擬屬性(參見 enum
的一個示例)。(由 Ethan Furman 在 bpo-19030 中貢獻。)
urllib¶
urllib.request
現在透過 DataHandler
類支援 data:
URL。(由 Mathias Panzenböck 在 bpo-16423 中貢獻。)
Request
類將使用的 http 方法現在可以透過在其子類上設定 method
類屬性來指定。(由 Jason R Coombs 在 bpo-18978 中貢獻。)
Request
物件現在可重用:如果 full_url
或 data
屬性被修改,所有相關的內部屬性都會更新。這意味著,例如,現在可以在多個 OpenerDirector.open()
呼叫中使用相同的 Request
物件,並帶有不同的 data 引數,或者修改 Request
的 url
而不是從頭開始重新計算。還有一個新的 remove_header()
方法可用於從 Request
中刪除請求頭。(由 Alexey Kachayev 在 bpo-16464,Daniel Wozniak 在 bpo-17485,以及 Damien Brecht 和 Senthil Kumaran 在 bpo-17272 中貢獻。)
HTTPError
物件現在有一個 headers
屬性,提供對與錯誤相關的 HTTP 響應頭的訪問。(由 Berker Peksag 在 bpo-15701 中貢獻。)
unittest¶
TestCase
類有一個新的方法 subTest()
,它生成一個上下文管理器,其 with
塊成為一個“子測試”。這個上下文管理器允許測試方法透過,例如,在迴圈內部呼叫 subTest
上下文管理器來動態生成子測試。單個測試方法因此可以生成無限數量的獨立識別和獨立計數的測試,所有這些測試都將執行,即使其中一個或多個失敗。例如
class NumbersTest(unittest.TestCase):
def test_even(self):
for i in range(6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
將產生六個子測試,每個子測試在 unittest 詳細輸出中都帶有一個標籤,該標籤由變數名 i
和該變數的特定值(i=0
,i=1
等)組成。有關此示例的完整版本,請參閱 使用子測試區分測試迭代。(由 Antoine Pitrou 在 bpo-16997 中貢獻。)
unittest.main()
現在接受一個可迭代的測試名稱作為 defaultTest,而之前它只接受單個測試名稱作為字串。(由 Jyrki Pulliainen 在 bpo-15132 中貢獻。)
如果在測試發現期間(即在測試檔案的模組級別)引發 SkipTest
,現在將其報告為跳過而不是錯誤。(由 Zach Ware 在 bpo-16935 中貢獻。)
discover()
現在對發現的檔案進行排序,以提供一致的測試順序。(由 Martin Melin 和 Jeff Ramnani 在 bpo-16709 中貢獻。)
如果測試成功,TestSuite
現在會在測試執行後立即刪除對測試的引用。在進行垃圾回收的 Python 直譯器上,如果沒有任何其他東西持有對測試的引用,這允許測試被垃圾回收。可以透過建立一個定義自定義 _removeTestAtIndex
方法的 TestSuite
子類來覆蓋此行為。(由 Tom Wardill, Matt McClure, 和 Andrew Svetlov 在 bpo-11798 中貢獻。)
一個新的測試斷言上下文管理器 assertLogs()
將確保給定的程式碼塊使用 logging
模組發出日誌訊息。預設情況下,訊息可以來自任何記錄器,並且優先順序為 INFO
或更高,但可以指定記錄器名稱和替代的最小日誌級別。上下文管理器返回的物件可以查詢已記錄的 LogRecord
和/或格式化的訊息。(由 Antoine Pitrou 在 bpo-18937 中貢獻。)
測試發現現在適用於名稱空間包(由 Claudiu Popa 在 bpo-17457 中貢獻)。
unittest.mock
物件現在在匹配呼叫時檢查其規範簽名,這意味著引數現在可以透過位置或名稱匹配,而不僅僅是透過位置。(由 Antoine Pitrou 在 bpo-17015 中貢獻。)
mock_open()
物件現在具有 readline
和 readlines
方法。(由 Toshio Kuratomi 在 bpo-17467 中貢獻。)
venv¶
venv
現在包含 csh
和 fish
shell 的啟用指令碼。(由 Andrew Svetlov 在 bpo-15417 中貢獻。)
EnvBuilder
和便捷函式 create()
接受一個新的關鍵字引數 with_pip,預設為 False
,它控制 EnvBuilder
是否確保在虛擬環境中安裝 pip
。(由 Nick Coghlan 在 bpo-19552 中作為 PEP 453 實現的一部分貢獻。)
wave¶
getparams()
方法現在返回一個具名元組而不是普通元組。(由 Claudiu Popa 在 bpo-17487 中貢獻。)
wave.open()
現在支援上下文管理協議。(由 Claudiu Popa 在 bpo-17616 中貢獻。)
wave
現在可以 將輸出寫入不可查詢的檔案。(由 David Jones, Guilherme Polo, 和 Serhiy Storchaka 在 bpo-5202 中貢獻。)
writeframesraw()
和 writeframes()
方法現在接受任何 bytes-like object。(由 Serhiy Storchaka 在 bpo-8311 中貢獻。)
weakref¶
新的 WeakMethod
類模擬了對繫結方法的弱引用。(由 Antoine Pitrou 在 bpo-14631 中貢獻。)
新的 finalize
類使得可以在物件被垃圾回收時註冊一個回撥函式,而無需仔細管理弱引用本身的生命週期。(由 Richard Oudkerk 在 bpo-15528 中貢獻。)
與 ref
關聯的回撥(如果有)現在透過 __callback__
屬性公開。(由 Mark Dickinson 在 bpo-17643 中貢獻。)
xml.etree¶
一個新的解析器,XMLPullParser
,允許非阻塞應用程式解析 XML 文件。一個示例可以在 用於非阻塞解析的 Pull API 中看到。(由 Antoine Pitrou 在 bpo-17741 中貢獻。)
xml.etree.ElementTree
的 tostring()
和 tostringlist()
函式,以及 ElementTree
的 write()
方法,現在有一個 short_empty_elements 僅限關鍵字引數,用於控制沒有內容的元素是以縮寫形式 (<tag />
) 還是擴充套件形式 (<tag></tag>
) 寫入。(由 Ariel Poliak 和 Serhiy Storchaka 在 bpo-14377 中貢獻。)
zipfile¶
PyZipFile
類的 writepy()
方法新增了一個 filterfunc 選項,可用於控制哪些目錄和檔案被新增到存檔中。例如,這可以用於從存檔中排除測試檔案。(由 Christian Tismer 在 bpo-19274 中貢獻。)
ZipFile
和 PyZipFile
的 allowZip64 引數現在預設為 True
。(由 William Mallard 在 bpo-17201 中貢獻。)
CPython 實現更改¶
PEP 445: CPython 記憶體分配器的定製¶
PEP 445 新增了 C 級別的介面,用於定製 CPython 直譯器中的記憶體分配。
參見
- PEP 445 —— 新增新的 API 以定製 Python 記憶體分配器
PEP 由 Victor Stinner 撰寫和實現。
PEP 442: 安全物件終結化¶
PEP 442 移除了 CPython 中物件終結化的當前限制和怪癖。透過它,具有 __del__()
方法的物件以及具有 finally
子句的生成器,可以在它們作為引用迴圈的一部分時被終結。
作為此更改的一部分,在大多數情況下,模組全域性變數在直譯器關閉期間不再被強制設定為 None
,而是依賴於迴圈垃圾收集器的正常操作。這避免了自迴圈 GC 首次引入以來一直困擾 Python 的一整類直譯器關閉時錯誤,這些錯誤通常涉及 __del__
方法。
參見
- PEP 442 —— 安全物件終結化
PEP 由 Antoine Pitrou 撰寫和實現。
PEP 456: 安全可互換雜湊演算法¶
PEP 456 延續了之前對 Python 雜湊演算法進行的安全修復工作,旨在解決面向公眾的 API(由字典查詢支援)可能遭受的某些 DOS 攻擊。(有關當前改進輪次的開始,請參閱 bpo-14621。)該 PEP 統一了 CPython 的雜湊程式碼,使得打包者更容易替換不同的雜湊演算法,並在具有 64 位資料型別的平臺上將 Python 的預設實現切換到 SipHash 實現。與舊的 FNV 演算法相比,效能差異微不足道。
該 PEP 向 sys.hash_info
命名元組添加了額外的欄位,以描述當前正在執行的二進位制檔案所使用的雜湊演算法。除此之外,該 PEP 不會更改任何現有的 CPython API。
PEP 436: Argument Clinic¶
“Argument Clinic” (PEP 436) 現在是 CPython 構建過程的一部分,可用於簡化為 C 中實現的內建函式和標準庫擴充套件模組定義和維護準確簽名。
一些標準庫擴充套件模組已轉換為在 Python 3.4 中使用 Argument Clinic,並且 pydoc
和 inspect
已相應更新。
預計在 Python 3.4 維護版本中,將向在 C 中實現的其他可呼叫物件新增用於程式化自省的簽名元資料。
備註
Argument Clinic PEP並未完全更新到實現的最新狀態。在這種情況下,版本管理器和核心開發團隊認為這是可以接受的,因為 Argument Clinic在 Python 3.4 中不會作為公共 API 提供給第三方使用。
參見
- PEP 436 —— Argument Clinic DSL
PEP 由 Larry Hastings 撰寫和實現。
其他構建和 C API 更改¶
新的
PyType_GetSlot()
函式已新增到穩定 ABI 中,允許在使用受限 API 時從命名型別槽檢索函式指標。(由 Martin von Löwis 在 bpo-17162 中貢獻。)新的
Py_SetStandardStreamEncoding()
預初始化 API 允許嵌入 CPython 直譯器的應用程式可靠地強制標準流使用特定的編碼和錯誤處理程式。(由 Bastien Montagne 和 Nick Coghlan 在 bpo-16129 中貢獻。)大多數不修改字串引數的 Python C API 現在都被正確標記為接受
const char *
而不是char *
。(由 Serhiy Storchaka 在 bpo-1772673 中貢獻。)新的 shell 版本的
python-config
即使在 python 直譯器不可用時(例如,在交叉編譯場景中)也可以使用。PyUnicode_FromFormat()
現在支援%s
,%A
,%U
,%V
,%S
, 和%R
的寬度和精度規範。(由 Ysj Ray 和 Victor Stinner 在 bpo-7330 中貢獻。)新函式
PyStructSequence_InitType2()
補充了現有的PyStructSequence_InitType()
函式。區別在於,它成功時返回0
,失敗時返回-1
。CPython 原始碼現在可以使用最新版本 GCC 和 clang 的地址健全性檢查功能進行編譯:小型物件分配器中的誤報已被消除。(由 Dhiru Kholia 在 bpo-18596 中貢獻。)
Windows 構建現在使用 地址空間佈局隨機化 和 資料執行預防。(由 Christian Heimes 在 bpo-16632 中貢獻。)
新函式
PyObject_LengthHint()
是operator.length_hint()
的 C API 等效項。(由 Armin Ronacher 在 bpo-16148 中貢獻。)
其他改進¶
python 命令新增了一個 選項
-I
,使其在“隔離模式”下執行,這意味著sys.path
既不包含指令碼目錄也不包含使用者的site-packages
目錄,並且所有PYTHON*
環境變數都將被忽略(它暗示-s
和-E
)。未來可能還會施加其他限制,目標是將指令碼的執行與使用者環境隔離。例如,當 Python 用於執行系統指令碼時,這是適當的。在大多數 POSIX 系統上,它可以在系統指令碼的#!
行中使用並應該使用。(由 Christian Heimes 在 bpo-16499 中貢獻。)在支援
readline
的系統上,互動式直譯器中預設啟用 Tab 補全。歷史記錄也預設啟用,並寫入(和讀取)檔案~/.python-history
。(由 Antoine Pitrou 和 Éric Araujo 在 bpo-5845 中貢獻。)使用
--version
呼叫 Python 直譯器現在將版本輸出到標準輸出而不是標準錯誤(bpo-18338)。argparse
(bpo-18920)和其他具有類似指令碼呼叫能力的模組也進行了類似的更改(bpo-18922)。CPython Windows 安裝程式現在在註冊擴充套件時將
.py
新增到PATHEXT
變數中,允許使用者在 Windows 命令提示符下僅透過鍵入指令碼名稱而無需.py
副檔名來執行 Python 指令碼。(由 Paul Moore 在 bpo-18569 中貢獻。)新的
make
目標 coverage-report 將構建 python,執行測試套件,並使用gcov
和 lcov 生成 C 程式碼庫的 HTML 覆蓋率報告。python 迴歸測試套件 的
-R
選項現在還使用sys.getallocatedblocks()
檢查記憶體分配洩漏。(由 Antoine Pitrou 在 bpo-13390 中貢獻。)python -m
現在適用於名稱空間包。stat
模組現在以 C 實現,這意味著它從 C 標頭檔案獲取其常量值,而不是像以前那樣在 python 模組中硬編碼這些值。從單個 OS 模組(
.so
,.dll
)載入多個 python 模組現在可以正常工作(以前它會靜默返回檔案中的第一個 python 模組)。(由 Václav Šmilauer 在 bpo-16421 中貢獻。)新增了一個操作碼
LOAD_CLASSDEREF
,用於修復類體中自由變數載入的錯誤,該錯誤可能因某些 __prepare__ 的使用而觸發。(由 Benjamin Peterson 在 bpo-17853 中貢獻。)Victor Stinner 使用他基於 PEP 445 的
pyfailmalloc
工具識別並修復了許多與 MemoryError 相關的崩潰(bpo-18408,bpo-18520)。pyvenv
命令現在接受--copies
選項,即使在預設使用符號連結的系統上,也可以使用副本而不是符號連結。(由 Vinay Sajip 在 bpo-18807 中貢獻。)pyvenv
命令還接受--without-pip
選項,以阻止將 pip 自動引導到虛擬環境中。 (由 Nick Coghlan 在 bpo-19552 中作為 PEP 453 實現的一部分貢獻。)PYTHONIOENCODING
環境變數值的編碼名稱現在是可選的。這使得只設置錯誤處理程式而不改變預設編碼成為可能。(由 Serhiy Storchaka 在 bpo-18818 中貢獻。)bz2
、lzma
和gzip
模組的open
函式現在支援x
(獨佔建立) 模式。(由 Tim Heaney 和 Vajrasky Kok 在 bpo-19201、bpo-19222 和 bpo-19223 中貢獻。)
顯著最佳化¶
UTF-32 解碼器的速度現在提高了 3 到 4 倍。(由 Serhiy Storchaka 在 bpo-14625 中貢獻。)
現在集合的雜湊衝突成本降低了。每次雜湊表探測都會在繼續透過雜湊表進行隨機探測之前,檢查一系列連續的相鄰鍵/雜湊對。這利用了快取區域性性,使衝突解決的成本更低。衝突解決方案可以描述為線性探測和開放定址的混合體。附加線性探測的數量預設為九個。這可以在編譯時透過將 LINEAR_PROBES 定義為任何值來更改。將 LINEAR_PROBES=0 設定為完全關閉線性探測。(由 Raymond Hettinger 在 bpo-18771 中貢獻。)
直譯器啟動速度提高了約 30%。有幾項措施促成了這種加速。直譯器在啟動時載入的模組更少,例如,預設不再匯入
re
、collections
和locale
模組及其依賴項。marshal 模組已得到改進,可以更快地載入編譯後的 Python 程式碼。(由 Antoine Pitrou、Christian Heimes 和 Victor Stinner 在 bpo-19219、bpo-19218、bpo-19209、bpo-19205 和 bpo-9548 中貢獻。)bz2.BZ2File
現在在大多數情況下與 Python2 版本一樣快或更快。lzma.LZMAFile
也已最佳化。(由 Serhiy Storchaka 和 Nadeem Vawda 在 bpo-16034 中貢獻。)對於小整數(最常見的用例),
random.getrandbits()
的速度提高了 20%-40%。(由 Serhiy Storchaka 在 bpo-16674 中貢獻。)透過利用新的字串儲存格式,字串的 pickle 化現在顯著加快了。(由 Victor Stinner 和 Antoine Pitrou 在 bpo-15596 中貢獻。)
已解決了
io.FileIO.readall()
中的效能問題。這尤其影響 Windows,並顯著加快了透過subprocess
傳遞大量資料的情況。(由 Richard Oudkerk 在 bpo-15758 中貢獻。)html.escape()
現在速度提高了 10 倍。(由 Matt Bryant 在 bpo-18020 中貢獻。)在 Windows 上,
obmalloc
中現在使用原生的VirtualAlloc
而不是 CRTmalloc
。人工基準測試顯示大約節省了 3% 的記憶體。os.urandom()
現在使用一個懶惰開啟的持久檔案描述符,以避免在多個執行緒並行執行時使用許多檔案描述符。(由 Antoine Pitrou 在 bpo-18756 中貢獻。)
已棄用¶
本節涵蓋了 Python 3.4 中已棄用並將在 Python 3.5 或更高版本中移除的各種 API 和其他功能。在大多數(但非全部)情況下,當直譯器在啟用棄用警告的情況下執行(例如,透過使用 -Wd
)時,使用已棄用的 API 將產生 DeprecationWarning
。
Python API 中的棄用¶
如 PEP 451: 匯入系統的 ModuleSpec 型別 所述,許多
importlib
方法和函式已棄用:importlib.find_loader()
已被importlib.util.find_spec()
替換;importlib.machinery.PathFinder.find_module()
已被importlib.machinery.PathFinder.find_spec()
替換;importlib.abc.MetaPathFinder.find_module()
已被importlib.abc.MetaPathFinder.find_spec()
替換;importlib.abc.PathEntryFinder.find_loader()
和find_module()
已被importlib.abc.PathEntryFinder.find_spec()
替換;所有xxxLoader
ABCload_module
方法(importlib.abc.Loader.load_module()
、importlib.abc.InspectLoader.load_module()
、importlib.abc.FileLoader.load_module()
、importlib.abc.SourceLoader.load_module()
)不應再實現,而是載入器應實現exec_module
方法(importlib.abc.Loader.exec_module()
、importlib.abc.InspectLoader.exec_module()
、importlib.abc.SourceLoader.exec_module()
)並讓匯入系統處理其餘部分;importlib.abc.Loader.module_repr()
、importlib.util.module_for_loader()
、importlib.util.set_loader()
和importlib.util.set_package()
不再需要,因為它們的功能現在由匯入系統自動處理。imp
模組正在等待棄用。為了保持與 Python 2/3 程式碼庫的相容性,該模組的移除目前尚未安排。formatter
模組正在等待棄用,並計劃在 Python 3.6 中移除。MD5
作為hmac.new()
函式的預設 digestmod 已被棄用。Python 3.6 將要求明確的摘要名稱或建構函式作為 digestmod 引數。ftplib
模組中的內部Netrc
類已在其文件字串中被標記為棄用已久。現在它會發出DeprecationWarning
,並將在 Python 3.5 中完全移除。subprocess.Popen.wait()
的未文件化的 endtime 引數不應該被公開,希望沒有被使用;它已被棄用,最有可能在 Python 3.5 中移除。HTMLParser
的 strict 引數已棄用。plistlib
的readPlist()
,writePlist()
,readPlistFromBytes()
和writePlistToBytes()
函式已棄用,取而代之的是相應的新函式load()
,dump()
,loads()
和dumps()
。Data()
已棄用,取而代之的是直接使用bytes
建構函式。sysconfig
鍵SO
已棄用,它已被EXT_SUFFIX
替換。各種
open
函式接受的U
模式已棄用。在 Python3 中,它沒有任何實際作用,應該替換為適當使用io.TextIOWrapper
(如果需要)及其 newline 引數。xml.etree.ElementTree.iterparse()
的 parser 引數已被棄用,XMLParser()
的 html 引數也已被棄用。為了為後者的移除做準備,XMLParser
的所有引數都應透過關鍵字傳遞。
已棄用的功能¶
使用
-n
標誌(無子程序)執行 IDLE — Python 編輯器和 shell 已棄用。但是,該功能在解決 bpo-18823 之前不會移除。如果存在,site 模組將“site-python”目錄新增到 sys.path 的功能已棄用(bpo-19375)。
已移除¶
不再支援的作業系統¶
已從原始碼和構建工具中移除對以下作業系統的支援
API 和功能移除¶
以下過時且先前已棄用的 API 和功能已被移除
未維護的
Misc/TextMate
和Misc/vim
目錄已被移除(請參閱 開發指南 以獲取替代建議)。SO
makefile 宏已移除(它已被SHLIB_SUFFIX
和EXT_SUFFIX
宏替換)(bpo-16754)。PyThreadState.tick_counter
欄位已移除;自 Python 3.2 引入“新 GIL”以來,其值已無意義(bpo-19199)。importlib
中的PyLoader
和PyPycLoader
已被移除。(由 Taras Lyapun 在 bpo-15641 中貢獻。)HTTPConnection
和HTTPSConnection
的 strict 引數已移除。HTTP 0.9 風格的“簡單響應”不再受支援。urllib.request.Request
已棄用的 getter 和 setter 方法add_data
,has_data
,get_data
,get_type
,get_host
,get_selector
,set_proxy
,get_origin_req_host
, 和is_unverifiable
已被移除(請改為直接訪問屬性)。marshal
中已移除對載入已棄用的TYPE_INT64
的支援。(由 Dan Riti 在 bpo-15480 中貢獻。)inspect.Signature
:現在要求僅位置引數具有有效的名稱。object.__format__()
不再接受非空格式字串,而是引發TypeError
。使用非空字串自 Python 3.2 以來已被棄用。此更改是為了防止先前正常工作(但錯誤)的程式碼在物件獲得處理它的 __format__ 方法後開始失敗的情況,這意味著如果您的程式碼正在使用's'
格式程式碼與沒有處理它的 __format__ 方法的物件,它現在可能會引發TypeError
。有關背景資訊,請參閱 bpo-7994。difflib.SequenceMatcher.isbjunk()
和difflib.SequenceMatcher.isbpopular()
在 3.2 中已被棄用,現在已移除:請使用x in sm.bjunk
和x in sm.bpopular
,其中 sm 是一個SequenceMatcher
物件(bpo-13248)。
程式碼清理¶
遷移到 Python 3.4¶
本節列出了前面描述過的變更以及其他可能需要修改程式碼的 bug 修復。
“python”命令列為的更改¶
在 POSIX shell 中,將
PATH
環境變數設定為空值等同於完全不設定它。但是,將PYTHONPATH
設定為空值 不 等同於完全不設定它:將PYTHONPATH
設定為空值等同於將其設定為.
,這在類比PATH
的工作方式時會導致混淆。現在的行為符合 POSIX 關於PATH
的約定。CPython 直譯器的除錯 (
--with-pydebug
) 構建的 [X refs, Y blocks] 輸出現在預設關閉。可以使用-X showrefcount
選項重新啟用它。(由 Ezio Melotti 在 bpo-17323 中貢獻。)python 命令和大多數標準庫指令碼(以及
argparse
)現在將--version
資訊輸出到stdout
而不是stderr
(有關問題列表,請參閱上面的 其他改進)。
Python API 的變化¶
importlib.abc
中定義的抽象基類 (ABC) 現在要麼引發適當的異常,要麼返回一個預設值,而不是盲目地引發NotImplementedError
。這隻會影響呼叫super()
並一直回溯到 ABC 的程式碼。為了相容性,請根據需要捕獲NotImplementedError
或相應的異常。模組型別現在預設將
__package__
和__loader__
屬性初始化為None
。要確定這些屬性是否以向後相容的方式設定,可以使用例如getattr(module, '__loader__', None) is not None
。(bpo-17115。)importlib.util.module_for_loader()
現在無條件地設定__loader__
和__package__
,以正確支援重新載入。如果不需要這種行為,則需要手動設定這些屬性。你可以使用importlib.util.module_to_load()
進行模組管理。重新載入時,匯入現在無條件地重置相關屬性(例如
__name__
、__loader__
、__package__
、__file__
、__cached__
)。請注意,這恢復了 3.3 之前的行為,意味著重新載入時會重新找到模組(bpo-19413)。凍結包不再將
__path__
設定為包含包名稱的列表,現在將其設定為空列表。之前的行為可能導致匯入系統在子模組匯入時出錯,如果存在與凍結包同名的目錄。判斷模組是否為包的正確方法是使用hasattr(module, '__path__')
(bpo-18065)。凍結模組不再定義
__file__
屬性。凍結模組設定該屬性在語義上是不正確的,因為它們並非從任何明確位置載入。如果你必須知道模組是否來自凍結程式碼,則可以檢查模組的__spec__.location
是否設定為'frozen'
,檢查載入器是否為importlib.machinery.FrozenImporter
的子類,或者如果需要 Python 2 相容性,可以使用imp.is_frozen()
。py_compile.compile()
現在會在寫入的檔案路徑是符號連結或非正則檔案時引發FileExistsError
。這是為了警告匯入系統將用正則檔案覆蓋這些檔案,無論它們最初是什麼型別的檔案路徑。importlib.abc.SourceLoader.get_source()
不再在載入的原始碼觸發SyntaxError
或UnicodeDecodeError
時引發ImportError
。由於ImportError
旨在僅在找不到原始碼但應該找到時引發,因此當找到原始碼但結構不正確時,這種過度使用/濫用其含義被認為是過度的。如果您之前捕獲 ImportError 並希望繼續忽略語法或解碼問題,現在請捕獲所有這三個異常。functools.update_wrapper()
和functools.wraps()
現在正確地將__wrapped__
屬性設定為被包裝的函式,即使該函式也設定了其__wrapped__
屬性。這意味著__wrapped__
屬性現在正確地連結了一堆裝飾函式,而不是鏈中的每個__wrapped__
屬性都指向最內層函式。假設之前行為是故意的自省庫可以使用inspect.unwrap()
訪問鏈中沒有__wrapped__
屬性的第一個函式。inspect.getfullargspec()
已在inspect.signature()
的基礎上重新實現,因此處理的可呼叫物件種類比過去多得多。預計在 Python 3.4 系列中,更多內建和擴充套件模組可呼叫物件將獲得簽名元資料。假設inspect.getfullargspec()
在非 Python 可呼叫物件上會失敗的程式碼可能需要進行相應調整。importlib.machinery.PathFinder
現在將當前工作目錄傳遞給sys.path_hooks
中的物件,用於空字串。這導致sys.path_importer_cache
永遠不會包含''
,因此基於sys.path
遍歷sys.path_importer_cache
將找不到所有鍵。在當前工作目錄中匯入的模組的__file__
現在也將具有絕對路徑,包括在使用直譯器-m
時(除了當指令碼直接使用相對路徑執行時__main__.__file__
)(由 Brett Cannon 在 bpo-18416 中貢獻)。是在命令列上指定的)(bpo-18416)。移除了
HTTPConnection
和HTTPSConnection
的 strict 引數,如果您按位置而不是按關鍵字指定其餘引數,這將改變它們的含義。如果您一直關注棄用警告,您的程式碼應該已經透過關鍵字指定了任何附加引數。from __future__ import ...
語句之間的字串現在 總是 引發SyntaxError
。以前,如果沒有前導文件字串,有時會忽略中間字串。這使得 CPython 符合語言規範;Jython 和 PyPy 已經符合。(bpo-17434)。ssl.SSLSocket.getpeercert()
和ssl.SSLSocket.do_handshake()
現在在SSLSocket
未連線時引發帶有ENOTCONN
的OSError
,而不是之前引發AttributeError
的行為。此外,如果握手尚未完成,getpeercert()
將引發ValueError
。base64.b32decode()
現在在輸入字串包含非 b32 字母表字元時引發binascii.Error
,而不是TypeError
。這個特定的TypeError
在其他TypeError
轉換時被遺漏。(由 Serhiy Storchaka 在 bpo-18011 中貢獻。)注意:此更改也無意中應用於 Python 3.3.3。當建立
cgi.FieldStorage
例項被垃圾回收時,file
屬性現在會自動關閉。如果您將檔案物件從cgi.FieldStorage
例項中單獨取出,並且沒有保持例項存活,那麼您應該儲存整個cgi.FieldStorage
例項,或者在cgi.FieldStorage
例項被垃圾回收之前讀取檔案內容。在關閉的 SSL 套接字上呼叫
read
或write
現在會引發一個資訊性的ValueError
,而不是之前更為神秘的AttributeError
(bpo-9177)。slice.indices()
不再對巨大的值產生OverflowError
。由於此修復,如果給定負長度,slice.indices()
現在會引發ValueError
;以前它會返回無意義的值(bpo-14794)。complex
建構函式,與cmath
函式不同,之前錯誤地接受了float
值,如果物件的__complex__
特殊方法返回一個。現在這將引發TypeError
。(bpo-16290)。3.2 和 3.3 中的
int
建構函式錯誤地接受了 base 引數的float
值。這不太可能有人這樣做,但如果是這樣,它現在會引發TypeError
(bpo-16772)。關鍵字專用引數的預設值現在在常規關鍵字引數的預設值 之後 評估,而不是之前。希望沒有人編寫依賴於先前錯誤行為的程式碼(bpo-16967)。
在
fork()
之後,過時的執行緒狀態現在被清除。這可能會導致一些以前被錯誤地永久保持活動的系統資源被釋放(例如,儲存線上程本地儲存中的資料庫連線)。(bpo-17094。)__annotations__
字典中的引數名稱現在已正確修飾,類似於__kwdefaults__
。(由 Yury Selivanov 在 bpo-20625 中貢獻。)hashlib.hash.name
現在總是返回小寫的識別符號。以前一些內建雜湊有大寫名稱,但現在它是一個正式的公共介面,命名已經保持一致(bpo-18532)。由於
unittest.TestSuite
現在在測試執行後會丟棄對測試的引用,因此重新使用TestSuite
重新執行一組測試的測試工具可能會失敗。測試套件不應以這種方式重複使用,因為這意味著狀態在測試執行之間保留,破壞了unittest
旨在提供的測試隔離。但是,如果認為缺乏隔離是可以接受的,則可以透過建立定義_removeTestAtIndex
方法什麼也不做的TestSuite
子類來恢復舊行為(參見TestSuite.__iter__()
)(bpo-11798)。unittest
現在使用argparse
進行命令列解析。以前某些無效的命令形式現在不再允許;理論上這不應該導致向後相容性問題,因為不允許的命令形式沒有任何意義,並且不太可能被使用。re.split()
、re.findall()
和re.sub()
函式,以及match
物件的group()
和groups()
方法,當要匹配的字串是 bytes-like object 時,現在總是返回一個 bytes 物件。以前返回型別與輸入型別匹配,因此如果您的程式碼依賴於返回值為,例如bytearray
,您將需要更改您的程式碼。audioop
函式現在如果傳遞字串輸入會立即引發錯誤,而不是隨機地在稍後失敗(bpo-16685)。HTMLParser
的新引數 convert_charrefs 目前預設為False
以實現向後相容性,但最終將更改為預設為True
。建議您將此關鍵字(帶適當的值)新增到程式碼中的任何HTMLParser
呼叫中(bpo-13633)。由於
hmac.new()
函式的 digestmod 引數將來不會有預設值,因此所有對hmac.new()
的呼叫都應更改為顯式指定 digestmod(bpo-17276)。呼叫
sysconfig.get_config_var()
時使用SO
鍵,或在sysconfig.get_config_vars()
呼叫的結果中查詢SO
已被棄用。此鍵應根據上下文替換為EXT_SUFFIX
或SHLIB_SUFFIX
(bpo-19555)。任何指定
U
的open
函式呼叫都應修改。U
在 Python3 中無效,如果使用最終會引發錯誤。根據函式,可以透過使用 newline 引數,或者必要時透過將流包裝在TextIOWrapper
中以使用其 newline 引數來實現其舊 Python2 行為的等效效果(bpo-15204)。如果您在指令碼中使用
pyvenv
並希望 不 安裝 pip,則必須在命令呼叫中新增--without-pip
。當指定縮排時,
json.dump()
和json.dumps()
的預設行為已更改:它不再在行尾的專案分隔逗號後生成尾隨空格。這隻有在您有對這種輸出進行空格敏感比較的測試時才會有影響(bpo-16333)。doctest
現在會在擴充套件模組的__doc__
字串中查詢 doctest,因此如果您的 doctest 測試發現包含看起來像 doctest 的擴充套件模組,那麼在執行測試時,您可能會看到以前從未見過的測試失敗(bpo-3158)。作為 Python 啟動改進的一部分,
collections.abc
模組進行了輕微重構。因此,匯入collections
不再自動匯入collections.abc
。如果您的程式依賴於(未文件化的)隱式匯入,則需要新增顯式import collections.abc
(bpo-20784)。
C API 的變化¶
PyEval_EvalFrameEx()
、PyObject_Repr()
和PyObject_Str()
以及其他一些內部 C API,現在包含一個除錯斷言,以確保它們不會在可能默默丟棄當前活動異常的情況下使用。在預期並希望丟棄活動異常的情況下(例如,因為它已經用PyErr_Fetch()
本地儲存,或正在故意用不同的異常替換),將需要顯式呼叫PyErr_Clear()
,以避免在呼叫這些操作(直接或間接)並在編譯時啟用斷言的 Python 版本上執行時觸發斷言。PyErr_SetImportError()
現在在其 msg 引數未設定時設定TypeError
。以前只返回NULL
且未設定異常。PyOS_ReadlineFunctionPointer
回撥的結果現在必須是由PyMem_RawMalloc()
或PyMem_RawRealloc()
分配的字串,或者如果發生錯誤,則為NULL
,而不是由PyMem_Malloc()
或PyMem_Realloc()
分配的字串(bpo-16742)PyThread_set_key_value()
現在總是設定值。在 Python 3.3 中,如果鍵已經存在(如果當前值是非NULL
指標),該函式什麼也不做。PyFrameObject
結構的f_tstate
(執行緒狀態)欄位已移除,以修復一個 bug:請參閱 bpo-14432 瞭解原因。
在 3.4.3 中更改¶
PEP 476:為標準庫 HTTP 客戶端預設啟用證書驗證¶
http.client
以及使用它的模組,例如 urllib.request
和 xmlrpc.client
,現在將預設驗證伺服器是否提供由平臺信任儲存中的 CA 簽名且其主機名與所請求的主機名匹配的證書,這顯著提高了許多應用程式的安全性。
對於需要舊有行為的應用程式,它們可以傳遞一個替代上下文
import urllib.request
import ssl
# This disables all verification
context = ssl._create_unverified_context()
# This allows using a specific certificate for the host, which doesn't need
# to be in the trust store
context = ssl.create_default_context(cafile="/path/to/file.crt")
urllib.request.urlopen("https://invalid-cert", context=context)