Python 3.5 中的新特性

編輯:

Elvis Pranskevichus <elvis@magic.io>, Yury Selivanov <yury@magic.io>

本文解釋了 Python 3.5 相較於 3.4 的新特性。Python 3.5 於 2015 年 9 月 13 日釋出。有關所有更改的完整列表,請參閱更新日誌

參見

PEP 478 - Python 3.5 釋出時間表

摘要 – 釋出亮點

新語法功能

  • PEP 492,帶有 async 和 await 語法的協程。

  • PEP 465,一個新的矩陣乘法運算子:a @ b

  • PEP 448,額外的解包泛化。

新庫模組

新的內建功能

  • bytes % argsbytearray % argsPEP 461 – 為 bytes 和 bytearray 新增 % 格式化。

  • 新的 bytes.hex()bytearray.hex()memoryview.hex() 方法。(由 Arnon Yaari 在 bpo-9951 中貢獻。)

  • memoryview 現在支援元組索引(包括多維)。(由 Antoine Pitrou 在 bpo-23632 中貢獻。)

  • 生成器新增 gi_yieldfrom 屬性,它返回正在被 yield from 表示式迭代的物件。(由 Benno Leslie 和 Yury Selivanov 在 bpo-24450 中貢獻。)

  • 當達到最大遞迴深度時,現在會引發新的 RecursionError 異常。(由 Georg Brandl 在 bpo-19235 中貢獻。)

CPython 實現改進

  • LC_TYPE 區域設定為 POSIX 區域設定(C 區域設定)時,sys.stdinsys.stdout 現在使用 surrogateescape 錯誤處理程式,而不是 strict 錯誤處理程式。(由 Victor Stinner 在 bpo-19977 中貢獻。)

  • .pyo 檔案不再使用,已被一種更靈活的方案取代,該方案在 .pyc 名稱中明確包含最佳化級別。(參見PEP 488 概述。)

  • 內建模組和擴充套件模組現在採用多階段過程進行初始化,這類似於 Python 模組的載入方式。(參見PEP 489 概述。)

標準庫的重大改進

安全改進

  • SSLv3 現在在整個標準庫中停用。它仍然可以透過手動例項化 ssl.SSLContext 來啟用。(有關更多詳細資訊,請參閱 bpo-22638;此更改已反向移植到 CPython 3.4 和 2.7。)

  • HTTP cookie 解析現在更嚴格,以防止潛在的注入攻擊。(由 Antoine Pitrou 在 bpo-22796 中貢獻。)

Windows 改進

  • 新的 Windows 安裝程式取代了舊的 MSI。有關更多資訊,請參閱在 Windows 上使用 Python

  • Windows 構建現在使用 Microsoft Visual C++ 14.0,擴充套件模組也應使用相同的版本。

請繼續閱讀,瞭解使用者面臨的更改的全面列表,包括許多其他較小的改進、CPython 最佳化、棄用和潛在的移植問題。

新功能

PEP 492 - 帶有 async 和 await 語法的協程

PEP 492 透過新增可等待物件協程函式非同步迭代非同步上下文管理器,極大地改進了 Python 中對非同步程式設計的支援。

協程函式使用新的 async def 語法宣告

>>> async def coro():
...     return 'spam'

在協程函式內部,新的 await 表示式可用於暫停協程執行,直到結果可用。任何物件都可以被 await,只要它透過定義 __await__() 方法實現了可等待協議。

PEP 492 還添加了 async for 語句,以便方便地迭代非同步可迭代物件。

使用新語法編寫的簡陋 HTTP 客戶端示例

import asyncio

async def http_get(domain):
    reader, writer = await asyncio.open_connection(domain, 80)

    writer.write(b'\r\n'.join([
        b'GET / HTTP/1.1',
        b'Host: %b' % domain.encode('latin-1'),
        b'Connection: close',
        b'', b''
    ]))

    async for line in reader:
        print('>>>', line)

    writer.close()

loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(http_get('example.com'))
finally:
    loop.close()

與非同步迭代類似,非同步上下文管理器也有新的語法。以下指令碼

import asyncio

async def coro(name, lock):
    print('coro {}: waiting for lock'.format(name))
    async with lock:
        print('coro {}: holding the lock'.format(name))
        await asyncio.sleep(1)
        print('coro {}: releasing the lock'.format(name))

loop = asyncio.get_event_loop()
lock = asyncio.Lock()
coros = asyncio.gather(coro(1, lock), coro(2, lock))
try:
    loop.run_until_complete(coros)
finally:
    loop.close()

將輸出

coro 2: waiting for lock
coro 2: holding the lock
coro 1: waiting for lock
coro 2: releasing the lock
coro 1: holding the lock
coro 1: releasing the lock

請注意,async forasync with 都只能在用 async def 宣告的協程函式內部使用。

協程函式旨在在相容的事件迴圈中執行,例如 asyncio 迴圈

備註

3.5.2 版中已更改: 從 CPython 3.5.2 開始,__aiter__ 可以直接返回非同步迭代器。返回可等待物件將導致 PendingDeprecationWarning

有關更多詳細資訊,請參閱非同步迭代器文件部分。

參見

PEP 492 – 帶有 async 和 await 語法的協程

PEP 由 Yury Selivanov 編寫並實現。

PEP 465 - 矩陣乘法的專用中綴運算子

PEP 465 添加了用於矩陣乘法的 @ 中綴運算子。目前,沒有內建的 Python 型別實現這個新運算子,但是,可以透過為常規、反射和原地矩陣乘法定義 __matmul__()__rmatmul__()__imatmul__() 來實現它。這些方法的語義類似於定義其他中綴算術運算子的方法。

矩陣乘法在數學、科學、工程等許多領域是一種非常常見的運算,新增 @ 可以編寫更簡潔的程式碼

S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)

而不是

S = dot((dot(H, beta) - r).T,
        dot(inv(dot(dot(H, V), H.T)), dot(H, beta) - r))

NumPy 1.10 支援新運算子

>>> import numpy

>>> x = numpy.ones(3)
>>> x
array([ 1., 1., 1.])

>>> m = numpy.eye(3)
>>> m
array([[ 1., 0., 0.],
       [ 0., 1., 0.],
       [ 0., 0., 1.]])

>>> x @ m
array([ 1., 1., 1.])

參見

PEP 465 – 矩陣乘法的專用中綴運算子

PEP 由 Nathaniel J. Smith 編寫;由 Benjamin Peterson 實現。

PEP 448 - 額外的解包泛化

PEP 448 擴充套件了 * 可迭代解包運算子和 ** 字典解包運算子的允許用法。現在可以在函式呼叫中使用任意數量的解包

>>> print(*[1], *[2], 3, *[4, 5])
1 2 3 4 5

>>> def fn(a, b, c, d):
...     print(a, b, c, d)
...

>>> fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4})
1 2 3 4

類似地,元組、列表、集合和字典顯示允許多次解包(參見表示式列表字典顯示

>>> *range(4), 4
(0, 1, 2, 3, 4)

>>> [*range(4), 4]
[0, 1, 2, 3, 4]

>>> {*range(4), 4, *(5, 6, 7)}
{0, 1, 2, 3, 4, 5, 6, 7}

>>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}

參見

PEP 448 – 額外的解包泛化

PEP 由 Joshua Landau 編寫;由 Neil Girdhar、Thomas Wouters 和 Joshua Landau 實現。

PEP 461 - bytes 和 bytearray 的百分號格式化支援

PEP 461bytesbytearray 添加了 % 插值運算子的支援。

雖然插值通常被認為是字串操作,但在某些情況下,對 bytesbytearrays 進行插值是有意義的,而彌補此功能缺失所需的工作會降低程式碼的整體可讀性。在處理線格式協議時,這個問題尤為重要,這些協議通常是二進位制和 ASCII 相容文字的混合。

示例:

>>> b'Hello %b!' % b'World'
b'Hello World!'

>>> b'x=%i y=%f' % (1, 2.5)
b'x=1 y=2.500000'

Unicode 不允許用於 %b,但它被 %a 接受(等同於 repr(obj).encode('ascii', 'backslashreplace')

>>> b'Hello %b!' % 'World'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: %b requires bytes, or an object that implements __bytes__, not 'str'

>>> b'price: %a' % '10€'
b"price: '10\\u20ac'"

請注意,%s%r 轉換型別雖然受支援,但應僅用於需要與 Python 2 相容的程式碼庫。

參見

PEP 461 – 為 bytes 和 bytearray 新增 % 格式化

PEP 由 Ethan Furman 編寫;由 Neil Schemenauer 和 Ethan Furman 實現。

PEP 484 - 型別提示

自 Python 3.0 版本以來(PEP 3107),函式註解語法一直是 Python 的一個特性,但註解的語義一直未定義。

經驗表明,大多數函式註解的用途是為函式引數和返回值提供型別提示。很明顯,如果標準庫包含型別註解的基本定義和工具,將對 Python 使用者有所裨益。

PEP 484 引入了一個臨時模組來提供這些標準定義和工具,以及一些在註解不可用情況下的約定。

例如,這是一個簡單的函式,其引數和返回型別在註解中宣告

def greeting(name: str) -> str:
    return 'Hello ' + name

雖然這些註解在執行時透過通常的 __annotations__ 屬性可用,但 執行時不會發生自動型別檢查。相反,假設會使用一個單獨的離線型別檢查器(例如 mypy)進行按需原始碼分析。

型別系統支援聯合型別、泛型型別以及一個名為 Any 的特殊型別,該型別與所有型別一致(即可以賦值給所有型別,也可以從所有型別賦值)。

參見

  • typing 模組文件

  • PEP 484 – 型別提示

    PEP 由 Guido van Rossum、Jukka Lehtosalo 和 Łukasz Langa 編寫;由 Guido van Rossum 實現。

  • PEP 483 – 型別提示的理論

    PEP 由 Guido van Rossum 編寫

PEP 471 - os.scandir() 函式 – 更好更快的目錄迭代器

PEP 471 向標準庫添加了一個新的目錄迭代函式 os.scandir()。此外,os.walk() 現在使用 scandir 實現,這使得它在 POSIX 系統上快 3 到 5 倍,在 Windows 系統上快 7 到 20 倍。這主要是透過大大減少遍歷目錄樹所需的 os.stat() 呼叫次數來實現的。

此外,scandir 返回一個迭代器,而不是返回一個檔名列表,這在迭代非常大的目錄時提高了記憶體效率。

以下示例展示了 os.scandir() 的簡單用法,以顯示給定 path 中不以 '.' 開頭的所有檔案(不包括目錄)。entry.is_file() 呼叫通常不會產生額外的系統呼叫

for entry in os.scandir(path):
    if not entry.name.startswith('.') and entry.is_file():
        print(entry.name)

參見

PEP 471 – os.scandir() 函式 – 更好更快的目錄迭代器

PEP 由 Ben Hoyt 在 Victor Stinner 的幫助下編寫並實現。

PEP 475: 重試因 EINTR 失敗的系統呼叫

當等待 I/O 的系統呼叫被訊號中斷時,會返回 errno.EINTR 錯誤程式碼。以前,在這種情況下,Python 會引發 InterruptedError。這意味著,在編寫 Python 應用程式時,開發人員有兩個選擇

  1. 忽略 InterruptedError

  2. 處理 InterruptedError 並在每個呼叫點嘗試重新啟動被中斷的系統呼叫。

第一個選項會導致應用程式間歇性失敗。第二個選項增加了大量的樣板程式碼,使程式碼幾乎無法閱讀。比較一下

print("Hello World")

while True:
    try:
        print("Hello World")
        break
    except InterruptedError:
        continue

PEP 475 實現了在 EINTR 情況下自動重試系統呼叫。這在大多數情況下消除了使用者程式碼中處理 EINTRInterruptedError 的負擔,並使 Python 程式(包括標準庫)更加健壯。請注意,僅當訊號處理程式不引發異常時,系統呼叫才會重試。

以下是現在在被訊號中斷時會重試的函式列表

參見

PEP 475 – 重試因 EINTR 失敗的系統呼叫

PEP 和實現由 Charles-François Natali 和 Victor Stinner 編寫,Antoine Pitrou(法國連線)協助。

PEP 479: 改變生成器內部 StopIteration 的處理方式

Python 3.4 及更早版本中生成器與 StopIteration 的互動有時令人驚訝,並可能隱藏難以發現的錯誤。以前,在生成器函式內部意外引發的 StopIteration 會被驅動生成器的迴圈構造解釋為迭代結束。

PEP 479 改變了生成器的行為:當在生成器內部引發 StopIteration 異常時,在它退出生成器幀之前,它會被替換為 RuntimeError。此更改的主要目標是簡化除錯,解決當不帶保護的 next() 呼叫引發 StopIteration 並導致由生成器控制的迭代靜默終止的情況。這與 yield from 構造結合使用時尤其有害。

這是一個向後不相容的更改,因此要啟用新行為,需要進行 __future__ 匯入

>>> from __future__ import generator_stop

>>> def gen():
...     next(iter([]))
...     yield
...
>>> next(gen())
Traceback (most recent call last):
  File "<stdin>", line 2, in gen
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: generator raised StopIteration

如果沒有 __future__ 匯入,當在生成器內部引發 StopIteration 異常時,將引發 PendingDeprecationWarning

參見

PEP 479 – 改變生成器內部 StopIteration 的處理方式

PEP 由 Chris Angelico 和 Guido van Rossum 編寫。由 Chris Angelico、Yury Selivanov 和 Nick Coghlan 實現。

PEP 485: 用於測試近似相等性的函式

PEP 485 添加了 math.isclose()cmath.isclose() 函式,它們用於判斷兩個值是否近似相等或“接近”。兩個值是否被認為是接近,由給定的絕對和相對容差決定。相對容差是 isclose 引數之間允許的最大差異,相對於較大的絕對值

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, rel_tol=1e-5)
True
>>> math.isclose(a, b, rel_tol=1e-6)
False

也可以使用絕對容差來比較兩個值,它必須是非負值

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, abs_tol=0.00003)
True
>>> math.isclose(a, b, abs_tol=0.00001)
False

參見

PEP 485 – 用於測試近似相等性的函式

PEP 由 Christopher Barker 編寫;由 Chris Barker 和 Tal Einat 實現。

PEP 486: 使 Python 啟動器感知虛擬環境

PEP 486 使 Windows 啟動器(參見PEP 397)能夠感知活動的虛擬環境。當使用預設直譯器且 VIRTUAL_ENV 環境變數已設定時,將使用虛擬環境中的直譯器。

參見

PEP 486 – 使 Python 啟動器感知虛擬環境

PEP 由 Paul Moore 編寫並實現。

PEP 488: 移除 PYO 檔案

PEP 488 廢棄了 .pyo 檔案的概念。這意味著 .pyc 檔案既表示未最佳化位元組碼,也表示最佳化位元組碼。為了避免不斷重新生成位元組碼檔案,當位元組碼被最佳化時,.pyc 檔案現在在其名稱中包含一個可選的 opt- 標籤。這帶來的副作用是,在 -O-OO 下執行時,不再出現位元組碼檔名衝突。因此,由 -O-OO 生成的位元組碼檔案現在可以同時存在。importlib.util.cache_from_source() 具有更新的 API 來幫助實現此更改。

參見

PEP 488 – 移除 PYO 檔案

PEP 由 Brett Cannon 編寫並實現。

PEP 489: 多階段擴充套件模組初始化

PEP 489 更新了擴充套件模組初始化,以利用 Python 3.4 中 PEP 451 引入的兩步模組載入機制。

此更改使選擇使用新機制的擴充套件模組的匯入語義更接近 Python 源模組和位元組碼模組的匯入語義,包括能夠使用任何有效的識別符號作為模組名稱,而不是僅限於 ASCII。

參見

PEP 489 – 多階段擴充套件模組初始化

PEP 由 Petr Viktorin、Stefan Behnel 和 Nick Coghlan 編寫;由 Petr Viktorin 實現。

其他語言更改

對核心 Python 語言做了一些較小的更改

  • 添加了 "namereplace" 錯誤處理程式。"backslashreplace" 錯誤處理程式現在支援解碼和轉換。(由 Serhiy Storchaka 在 bpo-19676bpo-22286 中貢獻。)

  • -b 選項現在影響 bytesint 的比較。(由 Serhiy Storchaka 在 bpo-23681 中貢獻。)

  • 新的哈薩克語 kz1048 和塔吉克語 koi8_t 編碼解碼器。(由 Serhiy Storchaka 在 bpo-22682bpo-22681 中貢獻。)

  • 屬性文件字串現在可寫。這對於 collections.namedtuple() 文件字串尤其有用。(由 Berker Peksag 在 bpo-24064 中貢獻。)

  • 現在支援涉及相對匯入的迴圈匯入。(由 Brett Cannon 和 Antoine Pitrou 在 bpo-17636 中貢獻。)

新模組

typing

新的 typing 臨時模組為函式型別註解提供了標準定義和工具。有關更多資訊,請參閱型別提示

zipapp

新的 zipapp 模組(在 PEP 441 中指定)提供了一個 API 和命令列工具,用於建立可執行的 Python Zip 應用程式,該功能在 Python 2.6 中透過 bpo-1739468 引入,但在當時或之後都沒有得到很好的宣傳。

使用新模組,打包應用程式就像將所有檔案(包括 __main__.py 檔案)放入目錄 myapp 並執行一樣簡單

$ python -m zipapp myapp
$ python myapp.pyz

該模組的實現由 Paul Moore 在 bpo-23491 中貢獻。

參見

PEP 441 – 改進 Python ZIP 應用程式支援

改進的模組

argparse

ArgumentParser 類現在允許透過將 allow_abbrev 設定為 False 來停用長選項的縮寫用法。(由 Jonathan Paugh、Steven Bethard、paul j3 和 Daniel Eriksson 在 bpo-14910 中貢獻。)

asyncio

由於 asyncio 模組是臨時的,因此 Python 3.5 中引入的所有更改也已反向移植到 Python 3.4.x。

Python 3.4.0 以來 asyncio 模組中的顯著更改

3.5.1 版中的更新

3.5.2 版中的更新

bz2

BZ2Decompressor.decompress 方法現在接受一個可選的 max_length 引數來限制解壓資料的最大大小。(由 Nikolaus Rath 在 bpo-15955 中貢獻。)

cgi

FieldStorage 類現在支援上下文管理器協議。(由 Berker Peksag 在 bpo-20289 中貢獻。)

cmath

一個新的函式 isclose() 提供了一種測試近似相等性的方法。(由 Chris Barker 和 Tal Einat 在 bpo-24270 中貢獻。)

code

InteractiveInterpreter.showtraceback() 方法現在會列印完整的鏈式回溯,就像互動式直譯器一樣。(由 Claudiu Popa 在 bpo-17442 中貢獻。)

collections

OrderedDict 類現在用 C 實現,使其速度提高了 4 到 100 倍。(由 Eric Snow 在 bpo-16991 中貢獻。)

OrderedDict.items()OrderedDict.keys()OrderedDict.values() 檢視現在支援 reversed() 迭代。(由 Serhiy Storchaka 在 bpo-19505 中貢獻。)

deque 類現在定義了 index()insert()copy(),並支援 +* 運算子。這使得 deque 可以被識別為 MutableSequence,並提高了它們與列表的可替換性。(由 Raymond Hettinger 在 bpo-23704 中貢獻。)

namedtuple() 生成的文件字串現在可以更新

Point = namedtuple('Point', ['x', 'y'])
Point.__doc__ += ': Cartesian coordinate'
Point.x.__doc__ = 'abscissa'
Point.y.__doc__ = 'ordinate'

(由 Berker Peksag 在 bpo-24064 中貢獻。)

UserString 類現在實現了 __getnewargs__()__rmod__()casefold()format_map()isprintable()maketrans() 方法,以匹配 str 的相應方法。(由 Joe Jevnik 在 bpo-22189 中貢獻。)

collections.abc

Sequence.index() 方法現在接受 startstop 引數,以匹配 tuplelist 等的相應方法。(由 Devin Jeanpierre 在 bpo-23086 中貢獻。)

一個新的 Generator 抽象基類。(由 Stefan Behnel 在 bpo-24018 中貢獻。)

新的 AwaitableCoroutineAsyncIteratorAsyncIterable 抽象基類。(由 Yury Selivanov 在 bpo-24184 中貢獻。)

對於早期的 Python 版本,新 ABC 的反向移植可在外部 PyPI 包中找到。

compileall

一個新的 compileall 選項 -j N 允許同時執行 N 個工作程序執行並行位元組碼編譯。compile_dir() 函式有一個相應的 workers 引數。(由 Claudiu Popa 在 bpo-16104 中貢獻。)

另一個新選項 -r 允許控制子目錄的最大遞迴級別。(由 Claudiu Popa 在 bpo-19628 中貢獻。)

-q 命令列選項現在可以多次指定,在這種情況下,所有輸出(包括錯誤)都將被抑制。compile_dir()compile_file()compile_path() 中相應的 quiet 引數現在可以接受一個整數值,表示輸出抑制的級別。(由 Thomas Kluyver 在 bpo-21338 中貢獻。)

concurrent.futures

Executor.map() 方法現在接受一個 chunksize 引數,允許批次處理任務,以在使用 ProcessPoolExecutor() 時提高效能。(由 Dan O’Reilly 在 bpo-11271 中貢獻。)

ThreadPoolExecutor 建構函式中的工作程序數量現在是可選的。預設值是 CPU 數量的 5 倍。(由 Claudiu Popa 在 bpo-21527 中貢獻。)

configparser

configparser 現在提供了一種透過在 ConfigParser 建構函式中指定轉換器字典,或在 ConfigParser 子類中將它們定義為方法來定製值轉換的方式。在解析器例項中定義的轉換器由其節代理繼承。

示例

>>> import configparser
>>> conv = {}
>>> conv['list'] = lambda v: [e.strip() for e in v.split() if e.strip()]
>>> cfg = configparser.ConfigParser(converters=conv)
>>> cfg.read_string("""
... [s]
... list = a b c d e f g
... """)
>>> cfg.get('s', 'list')
'a b c d e f g'
>>> cfg.getlist('s', 'list')
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> section = cfg['s']
>>> section.getlist('list')
['a', 'b', 'c', 'd', 'e', 'f', 'g']

(由 Łukasz Langa 在 bpo-18159 中貢獻。)

contextlib

新的 redirect_stderr() 上下文管理器(類似於 redirect_stdout())使得實用指令碼更容易處理將輸出寫入 sys.stderr 且不提供任何重定向選項的僵硬 API

>>> import contextlib, io, logging
>>> f = io.StringIO()
>>> with contextlib.redirect_stderr(f):
...     logging.warning('warning')
...
>>> f.getvalue()
'WARNING:root:warning\n'

(由 Berker Peksag 在 bpo-22389 中貢獻。)

csv

writerow() 方法現在支援任意可迭代物件,而不僅僅是序列。(由 Serhiy Storchaka 在 bpo-23171 中貢獻。)

curses

新的 update_lines_cols() 函式更新 LINESCOLS 模組變數。這對於檢測手動螢幕大小調整很有用。(由 Arnon Yaari 在 bpo-4254 中貢獻。)

dbm

當標誌值為 "n" 時,dumb.open 總是建立一個新的資料庫。(由 Claudiu Popa 在 bpo-18039 中貢獻。)

difflib

現在可以透過使用新的僅關鍵字引數 charset 來自定義 HtmlDiff.make_file() 生成的 HTML 文件的字元集。HTML 文件的預設字元集從 "ISO-8859-1" 更改為 "utf-8"。(由 Berker Peksag 在 bpo-2052 中貢獻。)

函式 diff_bytes() 現在可以比較位元組字串列表。這修復了 Python 2 中的一個迴歸。(由 Terry J. Reedy 和 Greg Ward 在 bpo-17445 中貢獻。)

distutils

buildbuild_ext 命令現在都接受 -j 選項,以啟用擴充套件模組的並行構建。(由 Antoine Pitrou 在 bpo-5309 中貢獻。)

distutils 模組現在支援 xz 壓縮,可以透過將 xztar 作為引數傳遞給 bdist --format 來啟用。(由 Serhiy Storchaka 在 bpo-16314 中貢獻。)

doctest

如果 module 不包含文件字串,DocTestSuite() 函式將返回一個空的 unittest.TestSuite,而不是引發 ValueError。(由 Glenn Jones 在 bpo-15916 中貢獻。)

email

一個新的策略選項 Policy.mangle_from_ 控制電子郵件正文中以 "From " 開頭的行是否由生成器新增 ">" 字元字首。對於 compat32,預設值為 True,對於所有其他策略,預設值為 False。(由 Milan Oberkirch 在 bpo-20098 中貢獻。)

一個新的 Message.get_content_disposition() 方法提供了方便訪問 Content-Disposition 標頭的規範值。(由 Abhilash Raj 在 bpo-21083 中貢獻。)

一個新的策略選項 EmailPolicy.utf8 可以設定為 True,以使用 UTF-8 字元集而不是編碼詞來編碼電子郵件標頭。這使得 Messages 可以根據 RFC 6532 進行格式化,並與支援 RFC 6531 SMTPUTF8 擴充套件的 SMTP 伺服器一起使用。(由 R. David Murray 在 bpo-24211 中貢獻。)

mime.text.MIMEText 建構函式現在接受一個 charset.Charset 例項。(由 Claude Paroz 和 Berker Peksag 在 bpo-16324 中貢獻。)

enum

如果只提供了 namesEnum 可呼叫物件有一個新的引數 start,用於指定列舉值的初始編號

>>> Animal = enum.Enum('Animal', 'cat dog', start=10)
>>> Animal.cat
<Animal.cat: 10>
>>> Animal.dog
<Animal.dog: 11>

(由 Ethan Furman 在 bpo-21706 中貢獻。)

faulthandler

enable()register()dump_traceback()dump_traceback_later() 函式現在除了接受檔案類物件外,還接受檔案描述符。(由 Wei Wu 在 bpo-23566 中貢獻。)

functools

lru_cache() 的大部分機制現在都在 C 語言中實現,這使其顯著加快。(由 Matt Joiner、Alexey Kachayev 和 Serhiy Storchaka 在 bpo-14373 中貢獻。)

glob

iglob()glob() 函式現在支援使用 "**" 模式進行子目錄遞迴搜尋。(由 Serhiy Storchaka 在 bpo-13968 中貢獻。)

gzip

GzipFile 建構函式的 mode 引數現在接受 "x" 以請求獨佔建立。(由 Tim Heaney 在 bpo-19222 中貢獻。)

heapq

merge() 中的元素比較現在可以透過在新的可選 key 關鍵字引數中傳遞 key 函式 進行自定義,並且可以使用新的可選 reverse 關鍵字引數來反轉元素比較

>>> import heapq
>>> a = ['9', '777', '55555']
>>> b = ['88', '6666']
>>> list(heapq.merge(a, b, key=len))
['9', '88', '777', '6666', '55555']
>>> list(heapq.merge(reversed(a), reversed(b), key=len, reverse=True))
['55555', '6666', '777', '88', '9']

(由 Raymond Hettinger 在 bpo-13742 中貢獻。)

http

一個新的 HTTPStatus 列舉,定義了一組 HTTP 狀態碼、原因短語和用英語編寫的長描述。(由 Demian Brecht 在 bpo-21793 中貢獻。)

http.client

當遠端伺服器連線意外關閉時,HTTPConnection.getresponse() 現在會引發 RemoteDisconnected 異常。此外,如果引發 ConnectionErrorRemoteDisconnected 是其子類),客戶端套接字現在會自動關閉,並在下次請求時重新連線

import http.client
conn = http.client.HTTPConnection('www.python.org')
for retries in range(3):
    try:
        conn.request('GET', '/')
        resp = conn.getresponse()
    except http.client.RemoteDisconnected:
        pass

(由 Martin Panter 在 bpo-3566 中貢獻。)

idlelib 和 IDLE

由於 idlelib 實現了 IDLE shell 和編輯器,並且不打算被其他程式匯入,因此它在每個版本中都得到了改進。有關自 3.4.0 以來以及未來 3.5.x 版本中所做的更改的累積列表,請參閱 Lib/idlelib/NEWS.txt。該檔案也可以從 IDLE 的 Help ‣ About IDLE 對話方塊中獲取。

imaplib

IMAP4 類現在支援 上下文管理器 協議。在 with 語句中使用時,IMAP4 LOGOUT 命令將在塊結束時自動呼叫。(由 Tarek Ziadé 和 Serhiy Storchaka 在 bpo-4972 中貢獻。)

imaplib 模組現在透過 IMAP4.enable() 方法支援 RFC 5161 (ENABLE 擴充套件) 和 RFC 6855 (UTF-8 支援)。一個新的 IMAP4.utf8_enabled 屬性跟蹤是否啟用了 RFC 6855 支援。(由 Milan Oberkirch、R. David Murray 和 Maciej Szulik 在 bpo-21800 中貢獻。)

根據 RFC 建議,imaplib 模組現在自動使用 UTF-8 編碼非 ASCII 字串的使用者名稱和密碼。(由 Milan Oberkirch 在 bpo-21800 中貢獻。)

imghdr

what() 函式現在識別 OpenEXR 格式 (由 Martin Vignali 和 Claudiu Popa 在 bpo-20295 中貢獻),以及 WebP 格式 (由 Fabrice Aneche 和 Claudiu Popa 在 bpo-20197 中貢獻)。

importlib

util.LazyLoader 類允許在啟動時間重要的應用程式中進行模組的延遲載入。(由 Brett Cannon 在 bpo-17621 中貢獻。)

abc.InspectLoader.source_to_code() 方法現在是一個靜態方法。這使得透過執行 exec(code, module.__dict__) 從字串編譯的程式碼初始化模組物件變得更容易。(由 Brett Cannon 在 bpo-21156 中貢獻。)

新的 util.module_from_spec() 函式現在是建立新模組的首選方式。與直接建立 types.ModuleType 例項不同,這個新函式將根據傳入的規範物件設定各種匯入控制屬性。(由 Brett Cannon 在 bpo-20383 中貢獻。)

inspect

SignatureParameter 類現在都是可序列化和可雜湊的。(由 Yury Selivanov 在 bpo-20726bpo-20334 中貢獻。)

一個新的 BoundArguments.apply_defaults() 方法提供了一種為缺失引數設定預設值的方法

>>> def foo(a, b='ham', *args): pass
>>> ba = inspect.signature(foo).bind('spam')
>>> ba.apply_defaults()
>>> ba.arguments
OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())])

(由 Yury Selivanov 在 bpo-24190 中貢獻。)

一個新的類方法 Signature.from_callable() 使 Signature 的子類化更容易。(由 Yury Selivanov 和 Eric Snow 在 bpo-17373 中貢獻。)

signature() 函式現在接受一個可選的關鍵字引數 follow_wrapped,當設定為 False 時,它會停用自動跟蹤 __wrapped__ 連結。(由 Yury Selivanov 在 bpo-20691 中貢獻。)

新增了一組用於檢查 協程函式協程物件 的新函式:iscoroutine()iscoroutinefunction()isawaitable()getcoroutinelocals()getcoroutinestate()。(由 Yury Selivanov 在 bpo-24017bpo-24400 中貢獻。)

stack()trace()getouterframes()getinnerframes() 函式現在返回一個命名元組列表。(由 Daniel Shahaf 在 bpo-16808 中貢獻。)

io

一個新的 BufferedIOBase.readinto1() 方法,最多隻呼叫底層原始流的 RawIOBase.read()RawIOBase.readinto() 方法一次。(由 Nikolaus Rath 在 bpo-20578 中貢獻。)

ipaddress

IPv4NetworkIPv6Network 類現在都接受 (address, netmask) 元組引數,以便從現有地址輕鬆構造網路物件

>>> import ipaddress
>>> ipaddress.IPv4Network(('127.0.0.0', 8))
IPv4Network('127.0.0.0/8')
>>> ipaddress.IPv4Network(('127.0.0.0', '255.0.0.0'))
IPv4Network('127.0.0.0/8')

(由 Peter Moody 和 Antoine Pitrou 在 bpo-16531 中貢獻。)

IPv4AddressIPv6Address 類的新屬性 reverse_pointer 返回反向 DNS PTR 記錄的名稱

>>> import ipaddress
>>> addr = ipaddress.IPv4Address('127.0.0.1')
>>> addr.reverse_pointer
'1.0.0.127.in-addr.arpa'
>>> addr6 = ipaddress.IPv6Address('::1')
>>> addr6.reverse_pointer
'1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa'

(由 Leon Weber 在 bpo-20480 中貢獻。)

json

json.tool 命令列介面現在保留輸入中 JSON 物件的鍵的順序。新的 --sort-keys 選項可用於按字母順序對鍵進行排序。(由 Berker Peksag 在 bpo-21650 中貢獻。)

JSON 解碼器現在引發 JSONDecodeError 而不是 ValueError,以提供更好的錯誤上下文資訊。(由 Serhiy Storchaka 在 bpo-19361 中貢獻。)

linecache

一個新的 lazycache() 函式可用於捕獲非檔案模組的資訊,以便稍後透過 getline() 獲取其行。這避免了在實際需要行之前進行 I/O 操作,而無需無限期地攜帶模組全域性變數。(由 Robert Collins 在 bpo-17911 中貢獻。)

locale

一個新的 delocalize() 函式可用於將字串轉換為標準化數字字串,並考慮 LC_NUMERIC 設定

>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC, 'de_DE.UTF-8')
'de_DE.UTF-8'
>>> locale.delocalize('1.234,56')
'1234.56'
>>> locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.delocalize('1,234.56')
'1234.56'

(由 Cédric Krier 在 bpo-13918 中貢獻。)

logging

所有日誌方法(Logger log()exception()critical()debug() 等)現在都接受異常例項作為 exc_info 引數,此外還接受布林值和異常元組

>>> import logging
>>> try:
...     1/0
... except ZeroDivisionError as ex:
...     logging.error('exception', exc_info=ex)
ERROR:root:exception

(由 Yury Selivanov 在 bpo-20537 中貢獻。)

handlers.HTTPHandler 類現在接受一個可選的 ssl.SSLContext 例項來配置 HTTP 連線中使用的 SSL 設定。(由 Alex Gaynor 在 bpo-22788 中貢獻。)

handlers.QueueListener 類現在接受一個 respect_handler_level 關鍵字引數,如果設定為 True,則會考慮處理程式級別將訊息傳遞給處理程式。(由 Vinay Sajip 貢獻。)

lzma

LZMADecompressor.decompress() 方法現在接受一個可選的 max_length 引數來限制解壓縮資料的最大大小。(由 Martin Panter 在 bpo-15955 中貢獻。)

math

math 模組中新增了兩個常量:infnan。(由 Mark Dickinson 在 bpo-23185 中貢獻。)

一個新的函式 isclose() 提供了一種測試近似相等性的方法。(由 Chris Barker 和 Tal Einat 在 bpo-24270 中貢獻。)

新增了一個 gcd() 函式。 fractions.gcd() 函式現已棄用。(由 Mark Dickinson 和 Serhiy Storchaka 在 bpo-22486 中貢獻。)

multiprocessing

sharedctypes.synchronized() 物件現在支援 上下文管理器 協議。(由 Charles-François Natali 在 bpo-21565 中貢獻。)

operator

attrgetter()itemgetter()methodcaller() 物件現在支援序列化。(由 Josh Rosenberg 和 Serhiy Storchaka 在 bpo-22955 中貢獻。)

新的 matmul()imatmul() 函式用於執行矩陣乘法。(由 Benjamin Peterson 在 bpo-21176 中貢獻。)

os

新增了返回 DirEntry 物件迭代器的新函式 scandir()。如果可能,scandir() 會在掃描目錄時提取檔案屬性,無需執行後續的系統呼叫來確定檔案型別或屬性,這可能會顯著提高效能。(由 Ben Hoyt 在 Victor Stinner 的幫助下在 bpo-22524 中貢獻。)

在 Windows 上,現在提供了一個新的 stat_result.st_file_attributes 屬性。它對應於 GetFileInformationByHandle() 返回的 BY_HANDLE_FILE_INFORMATION 結構體的 dwFileAttributes 成員。(由 Ben Hoyt 在 bpo-21719 中貢獻。)

urandom() 函式現在在 Linux 3.17 或更高版本上使用 getrandom() 系統呼叫,在 OpenBSD 5.6 或更高版本上使用 getentropy(),從而無需使用 /dev/urandom 並避免因潛在的檔案描述符耗盡而導致的故障。(由 Victor Stinner 在 bpo-22181 中貢獻。)

新的 get_blocking()set_blocking() 函式允許獲取和設定檔案描述符的阻塞模式 (O_NONBLOCK)。(由 Victor Stinner 在 bpo-22054 中貢獻。)

truncate()ftruncate() 函式現在在 Windows 上受支援。(由 Steve Dower 在 bpo-23668 中貢獻。)

新增了 os.path.commonpath() 函式,它返回每個傳入路徑名的最長公共子路徑。與 os.path.commonprefix() 函式不同,它總是返回一個有效路徑

>>> os.path.commonprefix(['/usr/lib', '/usr/local/lib'])
'/usr/l'

>>> os.path.commonpath(['/usr/lib', '/usr/local/lib'])
'/usr'

(由 Rafik Draoui 和 Serhiy Storchaka 在 bpo-10395 中貢獻。)

pathlib

新的 Path.samefile() 方法可用於檢查路徑是否指向與另一個路徑相同的檔案,另一個路徑可以是另一個 Path 物件,也可以是字串

>>> import pathlib
>>> p1 = pathlib.Path('/etc/hosts')
>>> p2 = pathlib.Path('/etc/../etc/hosts')
>>> p1.samefile(p2)
True

(由 Vajrasky Kok 和 Antoine Pitrou 在 bpo-19775 中貢獻。)

Path.mkdir() 方法現在接受一個新的可選引數 exist_ok,以匹配 mkdir -pos.makedirs() 的功能。(由 Berker Peksag 在 bpo-21539 中貢獻。)

新增了一個 Path.expanduser() 方法來擴充套件 ~~user 字首。(由 Serhiy Storchaka 和 Claudiu Popa 在 bpo-19776 中貢獻。)

一個新的 Path.home() 類方法可用於獲取表示使用者主目錄的 Path 例項。(由 Victor Salgado 和 Mayank Tripathi 在 bpo-19777 中貢獻。)

新的 Path.write_text()Path.read_text()Path.write_bytes()Path.read_bytes() 方法簡化了檔案的讀/寫操作。

以下程式碼片段將建立或重寫現有檔案 ~/spam42

>>> import pathlib
>>> p = pathlib.Path('~/spam42')
>>> p.expanduser().write_text('ham')
3

(由 Christopher Welborn 在 bpo-20218 中貢獻。)

pickle

現在可以使用早於協議版本 4 的 pickle 協議 序列化巢狀物件,例如未繫結的方法或巢狀類。協議版本 4 已經支援這些情況。(由 Serhiy Storchaka 在 bpo-23611 中貢獻。)

poplib

一個新的 POP3.utf8() 命令啟用 RFC 6856 (國際化電子郵件) 支援,如果 POP 伺服器支援它。(由 Milan OberKirch 在 bpo-21804 中貢獻。)

re

現在允許在後向斷言中使用對固定長度組的引用和條件引用

>>> import re
>>> pat = re.compile(r'(a|b).(?<=\1)c')
>>> pat.match('aac')
<_sre.SRE_Match object; span=(0, 3), match='aac'>
>>> pat.match('bbc')
<_sre.SRE_Match object; span=(0, 3), match='bbc'>

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

正則表示式中捕獲組的數量不再限制為 100。(由 Serhiy Storchaka 在 bpo-22437 中貢獻。)

sub()subn() 函式現在用空字串替換不匹配的組,而不是引發異常。(由 Serhiy Storchaka 在 bpo-1519638 中貢獻。)

re.error 異常現在具有新的屬性 msgpatternposlinenocolno,它們提供了更好的錯誤上下文資訊

>>> re.compile("""
...     (?x)
...     .++
... """)
Traceback (most recent call last):
   ...
sre_constants.error: multiple repeat at position 16 (line 3, column 7)

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

readline

一個新的 append_history_file() 函式可用於將歷史記錄中指定數量的尾隨元素追加到給定檔案。(由 Bruno Cauet 在 bpo-22940 中貢獻。)

selectors

新的 DevpollSelector 支援在 Solaris 上高效地 /dev/poll 輪詢。(由 Giampaolo Rodola' 在 bpo-18931 中貢獻。)

shutil

move() 函式現在接受 copy_function 引數,例如,如果移動時需要忽略檔案元資料,則允許使用 copy() 函式而不是預設的 copy2()。(由 Claudiu Popa 在 bpo-19840 中貢獻。)

make_archive() 函式現在支援 xztar 格式。(由 Serhiy Storchaka 在 bpo-5411 中貢獻。)

訊號

在 Windows 上,set_wakeup_fd() 函式現在也支援套接字控制代碼。(由 Victor Stinner 在 bpo-22018 中貢獻。)

signal 模組中的各種 SIG* 常量已轉換為 Enums。這允許在除錯期間列印有意義的名稱,而不是整數“魔術數字”。(由 Giampaolo Rodola' 在 bpo-21076 中貢獻。)

smtpd

SMTPServerSMTPChannel 類現在都接受 decode_data 關鍵字引數,以確定 SMTP 事務的 DATA 部分是否使用 "utf-8" 編解碼器解碼,或者作為位元組字串提供給 SMTPServer.process_message() 方法。出於向後相容性原因,預設值為 True,但在 Python 3.6 中將更改為 False。如果 decode_data 設定為 False,則 process_message 方法必須準備好接受關鍵字引數。(由 Maciej Szulik 在 bpo-19662 中貢獻。)

如果 decode_data 已設定為 True,則 SMTPServer 類現在會宣傳 8BITMIME 擴充套件 (RFC 6152)。如果客戶端在 MAIL 命令上指定 BODY=8BITMIME,它將透過 mail_options 關鍵字傳遞給 SMTPServer.process_message()。(由 Milan Oberkirch 和 R. David Murray 在 bpo-21795 中貢獻。)

SMTPServer 類現在還支援 SMTPUTF8 擴充套件 (RFC 6531: 國際化電子郵件)。如果客戶端在 MAIL 命令上指定 SMTPUTF8 BODY=8BITMIME,它們將透過 mail_options 關鍵字傳遞給 SMTPServer.process_message()。正確處理 SMTPUTF8 資料是 process_message 方法的責任。(由 Milan Oberkirch 在 bpo-21725 中貢獻。)

現在可以在 SMTPServer 建構函式中直接或透過名稱解析提供 IPv6 地址,並使其成功連線。(由 Milan Oberkirch 在 bpo-14758 中貢獻。)

smtplib

一個新的 SMTP.auth() 方法提供了一種方便的方式來實現自定義身份驗證機制。(由 Milan Oberkirch 在 bpo-15014 中貢獻。)

SMTP.set_debuglevel() 方法現在接受一個額外的除錯級別 (2),該級別在除錯訊息中啟用時間戳。(由 Gavin Chappell 和 Maciej Szulik 在 bpo-16914 中貢獻。)

SMTP.sendmail()SMTP.send_message() 方法現在都支援 RFC 6531 (SMTPUTF8)。(由 Milan Oberkirch 和 R. David Murray 在 bpo-22027 中貢獻。)

sndhdr

what()whathdr() 函式現在返回一個 namedtuple()。(由 Claudiu Popa 在 bpo-18615 中貢獻。)

socket

帶超時功能的函式現在使用單調時鐘,而不是系統時鐘。(由 Victor Stinner 在 bpo-22043 中貢獻。)

一個新的 socket.sendfile() 方法允許透過套接字傳送檔案,方法是在 UNIX 上使用高效能的 os.sendfile() 函式,從而使上傳速度比使用純 socket.send() 快 2 到 3 倍。(由 Giampaolo Rodola' 在 bpo-17552 中貢獻。)

socket.sendall() 方法不再每次接收或傳送位元組時重置套接字超時。套接字超時現在是傳送所有資料的最大總持續時間。(由 Victor Stinner 在 bpo-23853 中貢獻。)

socket.listen() 方法的 backlog 引數現在是可選的。預設情況下,它設定為 SOMAXCONN128,取較小者。(由 Charles-François Natali 在 bpo-21455 中貢獻。)

ssl

記憶體 BIO 支援

(由 Geert Jansen 在 bpo-21965 中貢獻。)

新增了 SSLObject 類,用於在 SSLSocket 的網路 I/O 功能不必要或不理想的情況下提供 SSL 協議支援。SSLObject 表示一個 SSL 協議例項,但不實現任何網路 I/O 方法,而是提供記憶體緩衝區介面。新的 MemoryBIO 類可用於在 Python 和 SSL 協議例項之間傳遞資料。

記憶體 BIO SSL 支援主要用於實現非同步 I/O 的框架,對於這些框架,SSLSocket 的就緒模型(“select/poll”)效率低下。

一個新的 SSLContext.wrap_bio() 方法可用於建立新的 SSLObject 例項。

應用層協議協商支援

(由 Benjamin Peterson 在 bpo-20188 中貢獻。)

在存在 OpenSSL 支援的情況下,ssl 模組現在實現了 RFC 7301 中描述的 應用層協議協商 TLS 擴充套件。

新的 SSLContext.set_alpn_protocols() 可用於指定套接字在 TLS 握手期間應宣傳哪些協議。

新的 SSLSocket.selected_alpn_protocol() 返回在 TLS 握手期間選擇的協議。HAS_ALPN 標誌指示是否存在 ALPN 支援。

其他更改

新增了一個 SSLSocket.version() 方法來查詢實際使用的協議版本。(由 Antoine Pitrou 在 bpo-20421 中貢獻。)

SSLSocket 類現在實現了 SSLSocket.sendfile() 方法。(由 Giampaolo Rodola' 在 bpo-17552 中貢獻。)

SSLSocket.send() 方法現在在非阻塞套接字上,如果操作會阻塞,則會引發 ssl.SSLWantReadErrorssl.SSLWantWriteError 異常。以前,它會返回 0。(由 Nikolaus Rath 在 bpo-20951 中貢獻。)

根據 RFC 5280cert_time_to_seconds() 函式現在將輸入時間解釋為 UTC 而不是本地時間。此外,返回值始終是 int。(由 Akira Li 在 bpo-19940 中貢獻。)

新的 SSLObject.shared_ciphers()SSLSocket.shared_ciphers() 方法返回客戶端在握手期間傳送的密碼列表。(由 Benjamin Peterson 在 bpo-23186 中貢獻。)

SSLSocket 類的 SSLSocket.do_handshake()SSLSocket.read()SSLSocket.shutdown()SSLSocket.write() 方法不再在每次接收或傳送位元組時重置套接字超時。套接字超時現在是方法的最大總持續時間。(由 Victor Stinner 在 bpo-23853 中貢獻。)

match_hostname() 函式現在支援 IP 地址匹配。(由 Antoine Pitrou 在 bpo-23239 中貢獻。)

sqlite3

Row 類現在完全支援序列協議,特別是 reversed() 迭代和切片索引。(由 Claudiu Popa 在 bpo-10203 中貢獻;由 Lucas Sinclair、Jessica McKellar 和 Serhiy Storchaka 在 bpo-13583 中貢獻。)

subprocess

新增了 run() 函式。它執行指定的命令並返回一個 CompletedProcess 物件,該物件描述了一個已完成的程序。新的 API 更一致,是 Python 程式碼中呼叫子程序的推薦方法,這些程式碼不需要保持與早期 Python 版本的相容性。(由 Thomas Kluyver 在 bpo-23342 中貢獻。)

示例:

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

sys

一個新的 set_coroutine_wrapper() 函式允許設定一個全域性鉤子,每當 協程物件async def 函式建立時,該鉤子就會被呼叫。相應的 get_coroutine_wrapper() 可用於獲取當前設定的包裝器。這兩個函式都是 臨時 的,僅用於除錯目的。(由 Yury Selivanov 在 bpo-24017 中貢獻。)

一個新的 is_finalizing() 函式可用於檢查 Python 直譯器是否正在 關閉。(由 Antoine Pitrou 在 bpo-22696 中貢獻。)

sysconfig

Windows 上使用者指令碼目錄的名稱現在包含 Python 版本的頭兩個元件。(由 Paul Moore 在 bpo-23437 中貢獻。)

tarfile

open() 函式的 mode 引數現在接受 "x" 以請求獨佔建立。(由 Berker Peksag 在 bpo-21717 中貢獻。)

TarFile.extractall()TarFile.extract() 方法現在接受一個關鍵字引數 numeric_owner。如果設定為 True,則提取的檔案和目錄將由 tar 檔案中的數字 uidgid 擁有。如果設定為 False(預設值,以及 3.5 版本之前的行為),它們將由 tar 檔案中指定的命名使用者和組擁有。(由 Michael Vogt 和 Eric Smith 在 bpo-23193 中貢獻。)

TarFile.list() 現在接受一個可選的 members 關鍵字引數,可以將其設定為 TarFile.getmembers() 返回列表的子集。(由 Serhiy Storchaka 在 bpo-21549 中貢獻。)

threading

Lock.acquire()RLock.acquire() 方法現在都使用單調時鐘進行超時管理。(由 Victor Stinner 在 bpo-22043 中貢獻。)

時間

monotonic() 函式現在始終可用。(由 Victor Stinner 在 bpo-22043 中貢獻。)

timeit

可以使用新的命令列選項 -u--unit=U 來指定計時器輸出的時間單位。支援的選項有 usecmsecsec。(由 Julian Gindi 在 bpo-18983 中貢獻。)

timeit() 函式新增了一個 globals 引數,用於指定程式碼執行的名稱空間。(由 Ben Roberts 在 bpo-2527 中貢獻。)

tkinter

用於在 Windows 上設定 Tcl/Tk 環境的 tkinter._fix 模組已被 _tkinter 模組中的一個私有函式取代,該函式不會對環境變數進行永久性更改。(由 Zachary Ware 在 bpo-20035 中貢獻。)

traceback

新的 walk_stack()walk_tb() 函式,方便遍歷幀和 回溯物件。(由 Robert Collins 在 bpo-17911 中貢獻。)

新的輕量級類:TracebackExceptionStackSummaryFrameSummary。(由 Robert Collins 在 bpo-17911 中貢獻。)

print_tb()print_stack() 函式現在都支援 limit 引數的負值。(由 Dmitry Kazakov 在 bpo-22619 中貢獻。)

types

一個新的 coroutine() 函式,用於將 生成器類生成器 物件轉換為 可等待物件。(由 Yury Selivanov 在 bpo-24017 中貢獻。)

新增了一個名為 CoroutineType 的型別,用於 async def 函式建立的 協程 物件。(由 Yury Selivanov 在 bpo-24400 中貢獻。)

unicodedata

unicodedata 模組現在使用 Unicode 8.0.0 的資料。

unittest

TestLoader.loadTestsFromModule() 方法現在接受一個僅限關鍵字引數 pattern,該引數作為第三個引數傳遞給 load_tests。現在無論找到的包的路徑是否與 pattern 匹配,都會檢查其是否存在 load_tests,因為包名不可能匹配預設模式。(由 Robert Collins 和 Barry A. Warsaw 在 bpo-16662 中貢獻。)

單元測試發現錯誤現在在 TestLoader 例項的 TestLoader.errors 屬性中公開。(由 Robert Collins 在 bpo-19746 中貢獻。)

新增命令列選項 --locals,用於在回溯中顯示區域性變數。(由 Robert Collins 在 bpo-22936 中貢獻。)

unittest.mock

Mock 類有以下改進

  • 類建構函式新增了 unsafe 引數,該引數會使 mock 物件在屬性名稱以 "assert" 開頭時引發 AttributeError。(由 Kushal Das 在 bpo-21238 中貢獻。)

  • 新增 Mock.assert_not_called() 方法,用於檢查 mock 物件是否被呼叫。(由 Kushal Das 在 bpo-21262 中貢獻。)

MagicMock 類現在支援 __truediv__()__divmod__()__matmul__() 運算子。(由 Johannes Baiter 在 bpo-20968,以及 Håkan Lövdahl 在 bpo-23581bpo-23568 中貢獻。)

在修補內建名稱時,不再需要顯式將 create=True 傳遞給 patch() 函式。(由 Kushal Das 在 bpo-17660 中貢獻。)

urllib

新增 request.HTTPPasswordMgrWithPriorAuth 類,允許管理 HTTP 基本認證憑據,以消除不必要的 401 響應處理,或在第一次請求時無條件傳送憑據,以便與返回 404 響應而不是 401 的伺服器通訊,如果未傳送 Authorization 標頭。(由 Matej Cepl 在 bpo-19494 和 Akshit Khurana 在 bpo-7159 中貢獻。)

parse.urlencode() 函式新增了 quote_via 引數,在需要時提供了一種控制查詢部分編碼的方式。(由 Samwyse 和 Arnon Yaari 在 bpo-13866 中貢獻。)

request.urlopen() 函式接受一個 ssl.SSLContext 物件作為 context 引數,該物件將用於 HTTPS 連線。(由 Alex Gaynor 在 bpo-22366 中貢獻。)

parse.urljoin() 已更新,以使用 RFC 3986 語義來解析相對 URL,而不是 RFC 1808RFC 2396。(由 Demian Brecht 和 Senthil Kumaran 在 bpo-22118 中貢獻。)

wsgiref

headers.Headers 類建構函式的 headers 引數現在是可選的。(由 Pablo Torres Navarrete 和 SilentGhost 在 bpo-5800 中貢獻。)

xmlrpc

client.ServerProxy 類現在支援 上下文管理器 協議。(由 Claudiu Popa 在 bpo-20627 中貢獻。)

client.ServerProxy 建構函式現在接受一個可選的 ssl.SSLContext 例項。(由 Alex Gaynor 在 bpo-22960 中貢獻。)

xml.sax

SAX 解析器現在支援 xmlreader.InputSource 物件的字元流。(由 Serhiy Storchaka 在 bpo-2175 中貢獻。)

parseString() 現在接受一個 str 例項。(由 Serhiy Storchaka 在 bpo-10590 中貢獻。)

zipfile

ZIP 輸出現在可以寫入不可查詢的流。(由 Serhiy Storchaka 在 bpo-23252 中貢獻。)

ZipFile.open() 方法的 mode 引數現在接受 "x",以請求獨佔建立。(由 Serhiy Storchaka 在 bpo-21717 中貢獻。)

其他模組級更改

mmapossaudiodevsocketsslcodecs 模組中的許多函式現在接受可寫的 類位元組物件。(由 Serhiy Storchaka 在 bpo-23001 中貢獻。)

最佳化

os.walk() 函式在 POSIX 系統上速度提高了 3 到 5 倍,在 Windows 上速度提高了 7 到 20 倍。這是透過使用新的 os.scandir() 函式實現的,該函式公開了底層 readdirFindFirstFile/FindNextFile 系統呼叫的檔案資訊。(由 Ben Hoyt 在 Victor Stinner 的幫助下在 bpo-23605 中貢獻。)

bytes(int) (用零位元組填充) 的構造對於大型物件更快,並使用更少的記憶體。使用 calloc() 而不是 malloc() 來為這些物件分配記憶體。(由 Victor Stinner 在 bpo-21233 中貢獻。)

ipaddress IPv4NetworkIPv6Network 的一些操作已大幅加速,例如 subnets()supernet()summarize_address_range()collapse_addresses()。速度可以提高 3 到 15 倍。(由 Antoine Pitrou、Michel Albert 和 Markus 在 bpo-21486bpo-21487bpo-20826bpo-23266 中貢獻。)

ipaddress 物件的 pickle 序列化已最佳化,以生成明顯更小的輸出。(由 Serhiy Storchaka 在 bpo-23133 中貢獻。)

io.BytesIO 上的許多操作現在速度提高了 50% 到 100%。(由 Serhiy Storchaka 在 bpo-15381 和 David Wilson 在 bpo-22003 中貢獻。)

marshal.dumps() 函式現在更快:版本 3 和 4 提高了 65–85%,版本 0 到 2 在典型資料上提高了 20–25%,在最佳情況下甚至提高了 5 倍。(由 Serhiy Storchaka 在 bpo-20416bpo-23344 中貢獻。)

UTF-32 編碼器現在速度提高了 3 到 7 倍。(由 Serhiy Storchaka 在 bpo-15027 中貢獻。)

正則表示式現在解析速度提高了 10%。(由 Serhiy Storchaka 在 bpo-19380 中貢獻。)

json.dumps() 函式已最佳化,使其在 ensure_ascii=False 時與在 ensure_ascii=True 時一樣快。(由 Naoki Inada 在 bpo-23206 中貢獻。)

PyObject_IsInstance()PyObject_IsSubclass() 函式在第二個引數的元類是 type 的常見情況下已加速。(由 Georg Brandl 在 bpo-22540 中貢獻。)

方法快取略有改進,在某些基準測試中效能提高了 5%。(由 Antoine Pitrou 在 bpo-22847 中貢獻。)

random 模組的物件在 64 位構建中現在使用減少 50% 的記憶體。(由 Serhiy Storchaka 在 bpo-23488 中貢獻。)

property() getter 呼叫速度提高了 25%。(由 Joe Jevnik 在 bpo-23910 中貢獻。)

fractions.Fraction 的例項化現在速度提高了 30%。(由 Stefan Behnel 在 bpo-22464 中貢獻。)

字串方法 find()rfind()split()partition()in 字串運算子在搜尋 1 字元子字串時現在顯著更快。(由 Serhiy Storchaka 在 bpo-23573 中貢獻。)

構建和 C API 更改

新增了 calloc 函式

(由 Victor Stinner 在 bpo-21233 中貢獻。)

新增編碼/解碼輔助函式

(由 Victor Stinner 在 bpo-18395 中貢獻。)

新增 PyCodec_NameReplaceErrors() 函式,用於將 Unicode 編碼錯誤替換為 \N{...} 轉義序列。(由 Serhiy Storchaka 在 bpo-19676 中貢獻。)

新增 PyErr_FormatV() 函式,類似於 PyErr_Format(),但接受 va_list 引數。(由 Antoine Pitrou 在 bpo-18711 中貢獻。)

新增 PyExc_RecursionError 異常。(由 Georg Brandl 在 bpo-19235 中貢獻。)

PEP 489 引入了新的 PyModule_FromDefAndSpec()PyModule_FromDefAndSpec2()PyModule_ExecDef() 函式——多階段擴充套件模組初始化。(由 Petr Viktorin 在 bpo-24268 中貢獻。)

新的 PyNumber_MatrixMultiply()PyNumber_InPlaceMatrixMultiply() 函式,用於執行矩陣乘法。(由 Benjamin Peterson 在 bpo-21176 中貢獻。詳情請參閱 PEP 465。)

PyTypeObject.tp_finalize 插槽現在是穩定 ABI 的一部分。

Windows 構建現在需要 Microsoft Visual C++ 14.0,該版本可在 Visual Studio 2015 中獲取。

在某些平臺上,擴充套件模組的檔名現在包含平臺資訊標籤(該標籤是可選的,CPython 將匯入沒有它的擴充套件,但如果標籤存在且不匹配,則不會載入擴充套件)

  • 在 Linux 上,擴充套件模組檔名以 .cpython-<major><minor>m-<architecture>-<os>.pyd 結尾

    • <major> 是 Python 版本的主版本號;對於 Python 3.5,這是 3

    • <minor> 是 Python 版本的次版本號;對於 Python 3.5,這是 5

    • <architecture> 是構建擴充套件模組以執行的硬體架構。最常見的是 32 位 Intel 平臺的 i386 或 64 位 Intel (和 AMD) 平臺的 x86_64

    • <os> 始終是 linux-gnu,除非是為在 64 位平臺上與 32 位 ABI 通訊而構建的擴充套件,在這種情況下它是 linux-gnu32 (並且 <architecture> 將是 x86_64)。

  • 在 Windows 上,擴充套件模組檔名以 <debug>.cp<major><minor>-<platform>.pyd 結尾

    • <major> 是 Python 版本的主版本號;對於 Python 3.5,這是 3

    • <minor> 是 Python 版本的次版本號;對於 Python 3.5,這是 5

    • <platform> 是構建擴充套件模組的平臺,對於 Win32 是 win32,對於 Win64 是 win_amd64,對於 Windows Itanium 64 是 win_ia64,對於 ARM 上的 Windows 是 win_arm

    • 如果在除錯模式下構建,<debug> 將是 _d,否則為空。

  • 在 OS X 平臺上,擴充套件模組檔名現在以 -darwin.so 結尾。

  • 在所有其他平臺上,擴充套件模組檔名與 Python 3.4 相同。

已棄用

新關鍵字

不建議使用 asyncawait 作為變數、類、函式或模組名稱。它們由 PEP 492 在 Python 3.5 中引入,並將在 Python 3.7 中成為正式關鍵字。

已廢棄的 Python 行為

在生成器內部引發 StopIteration 異常現在將生成一個靜默的 PendingDeprecationWarning,在 Python 3.6 中將變為非靜默的廢棄警告,並在 Python 3.7 中觸發 RuntimeError。有關詳細資訊,請參閱 PEP 479: 更改生成器內部的 StopIteration 處理方式

不支援的作業系統

Windows XP 不再受 Microsoft 支援,因此,根據 PEP 11,CPython 3.5 不再正式支援此作業系統。

已棄用的 Python 模組、函式和方法

formatter 模組現在已完全廢棄,並仍計劃在 Python 3.6 中移除。

asyncio.async() 函式已被廢棄,推薦使用 ensure_future()

smtpd 模組過去總是使用 utf-8 編解碼器解碼電子郵件訊息的 DATA 部分。現在可以透過 SMTPServer 的新 decode_data 關鍵字來控制。預設值為 True,但此預設值已被廢棄。請指定具有適當值的 decode_data 關鍵字以避免廢棄警告。

直接將值賦給 http.cookies.Morsel 物件的 keyvaluecoded_value 已被廢棄。請改用 set() 方法。此外,set() 的未文件化引數 LegalChars 已被廢棄,現在將被忽略。

將格式字串作為關鍵字引數 format_string 傳遞給 string.Formatter 類的 format() 方法已廢棄。(由 Serhiy Storchaka 在 bpo-23671 中貢獻。)

platform.dist()platform.linux_distribution() 函式現在已廢棄。Linux 發行版使用太多不同的方式來描述自己,因此該功能留給了軟體包。(由 Vajrasky Kok 和 Berker Peksag 在 bpo-1322 中貢獻。)

inspect.Signature 的先前未文件化的 from_functionfrom_builtin 方法已被廢棄。請改用新的 Signature.from_callable() 方法。(由 Yury Selivanov 在 bpo-24248 中貢獻。)

inspect.getargspec() 函式已被廢棄,並計劃在 Python 3.6 中移除。(詳情請參閱 bpo-20438。)

inspect getfullargspec()getcallargs()formatargspec() 函式已被廢棄,推薦使用 inspect.signature() API。(由 Yury Selivanov 在 bpo-20438 中貢獻。)

getargvalues()formatargvalues() 函式在 Python 3.5.0 釋出時意外地被標記為廢棄。

在字串模式或 re.ASCII 中使用 re.LOCALE 標誌現在已被廢棄。(由 Serhiy Storchaka 在 bpo-22407 中貢獻。)

在正則表示式模式和替換模式中,使用由 '\' 和 ASCII 字母組成的不被識別的特殊序列現在會引發廢棄警告,並將在 Python 3.6 中被禁止。(由 Serhiy Storchaka 在 bpo-23622 中貢獻。)

unittest.TestLoader.loadTestsFromModule() 方法的未文件化和非官方的 use_load_tests 預設引數現在已被廢棄並忽略。(由 Robert Collins 和 Barry A. Warsaw 在 bpo-16662 中貢獻。)

已移除

API 和功能移除

以下過時且先前已廢棄的 API 和功能已被移除

  • email 包已刪除 __version__ 屬性。email 程式碼已長時間未與標準庫分開提供,且 __version__ 字串在最近幾個版本中未更新。

  • ftplib 模組中的內部 Netrc 類在 3.4 中已廢棄,現在已被移除。(由 Matt Chaput 在 bpo-6623 中貢獻。)

  • .pyo 檔案的概念已被移除。

  • 在臨時 asyncio 模組中的 JoinableQueue 類在 3.4.4 中已廢棄,現在已被移除。(由 A. Jesse Jiryu Davis 在 bpo-23464 中貢獻。)

移植到 Python 3.5

本節列出了前面描述過的變更以及其他可能需要修改程式碼的 bug 修復。

Python 行為的改變

  • 由於疏忽,早期 Python 版本錯誤地接受了以下語法

    f(1 for x in [1], *args)
    f(1 for x in [1], **kwargs)
    

    Python 3.5 現在正確地引發 SyntaxError,因為生成器表示式如果不是函式的唯一引數,則必須用括號括起來。

Python API 的變化

  • PEP 475:系統呼叫現在在被訊號中斷時會重試,而不是在 Python 訊號處理程式不引發異常時引發 InterruptedError

  • 在 Python 3.5 之前,如果 datetime.time 物件表示 UTC 午夜,則認為它為假。此行為被認為是晦澀且容易出錯的,已在 Python 3.5 中移除。有關詳細資訊,請參閱 bpo-13936

  • ssl.SSLSocket.send() 方法現在在非阻塞套接字上如果操作會阻塞,則會引發 ssl.SSLWantReadErrorssl.SSLWantWriteError。以前,它會返回 0。(由 Nikolaus Rath 在 bpo-20951 中貢獻。)

  • 生成器的 __name__ 屬性現在從函式名稱設定,而不是從程式碼名稱設定。使用 gen.gi_code.co_name 檢索程式碼名稱。生成器還具有新的 __qualname__ 屬性,即限定名稱,現在用於表示生成器 (repr(gen))。(由 Victor Stinner 在 bpo-21205 中貢獻。)

  • 已移除 HTMLParserHTMLParser.error() 的廢棄“嚴格”模式和引數,以及 HTMLParserError 異常。(由 Ezio Melotti 在 bpo-15114 中貢獻。) HTMLParserconvert_charrefs 引數現在預設為 True。(由 Berker Peksag 在 bpo-21047 中貢獻。)

  • 儘管它不是 API 的正式部分,但為了移植目的(即:修復測試),值得注意的是,以前形式為“'sometype' 不支援緩衝區協議”的錯誤訊息現在形式為“需要 類位元組物件,而不是 'sometype'”。(由 Ezio Melotti 在 bpo-16518 中貢獻。)

  • 如果當前目錄設定為不再存在的目錄,則不再引發 FileNotFoundError,而是 find_spec() 將返回 None,但 sys.path_importer_cache 中快取 None,這與典型情況不同 (bpo-22834)。

  • http.clienthttp.server 中的 HTTP 狀態程式碼和訊息被重構為一個公共的 HTTPStatus 列舉。為了向後相容,http.clienthttp.server 中的值仍然可用。(由 Demian Brecht 在 bpo-21793 中貢獻。)

  • 當匯入載入器定義 exec_module() 時,現在也期望它定義 create_module() (現在會引發 DeprecationWarning,在 Python 3.6 中將是錯誤)。如果載入器繼承自 importlib.abc.Loader,則無需執行任何操作,否則只需定義 create_module() 返回 None。(由 Brett Cannon 在 bpo-23014 中貢獻。)

  • re.split() 函式總是忽略空模式匹配,因此 "x*" 模式與 "x+" 的工作方式相同,並且 "\b" 模式從不起作用。現在,如果模式可能匹配空字串,re.split() 會引發警告。為了相容性,請使用從不匹配空字串的模式(例如 "x+" 而不是 "x*")。只能匹配空字串的模式(例如 "\b")現在會引發錯誤。(由 Serhiy Storchaka 在 bpo-22818 中貢獻。)

  • http.cookies.Morsel 字典式介面已實現自洽:morsel 比較現在考慮 keyvaluecopy() 現在返回 Morsel 例項而不是 dict,並且 update() 現在如果更新字典中的任何鍵無效將引發異常。此外,set() 的未文件化 LegalChars 引數已被廢棄並現在被忽略。(由 Demian Brecht 在 bpo-2211 中貢獻。)

  • PEP 488 已從 Python 中移除 .pyo 檔案,並在 .pyc 檔名中引入了可選的 opt- 標籤。importlib.util.cache_from_source() 增加了 optimization 引數以幫助控制 opt- 標籤。因此,該函式的 debug_override 引數現已廢棄。.pyo 檔案也不再支援作為 Python 直譯器的檔案引數,因此單獨分發時沒有任何用途(即無原始碼分發)。由於 Python 3.5 中位元組碼的魔術數字已更改,因此無論此 PEP 如何,所有舊版 Python 的 .pyo 檔案都無效。

  • socket 模組現在在 Linux 3.6 及更高版本上匯出 CAN_RAW_FD_FRAMES 常量。

  • ssl.cert_time_to_seconds() 函式現在根據 RFC 5280 將輸入時間解釋為 UTC,而不是本地時間。此外,返回值始終是 int。(由 Akira Li 在 bpo-19940 中貢獻。)

  • pygettext.py 工具現在在 POT-Creation-Date 標頭中使用標準 +NNNN 時區格式。

  • smtplib 模組現在使用 sys.stderr 而不是以前的模組級 stderr 變數進行除錯輸出。如果您的(測試)程式依賴於修補模組級變數來捕獲除錯輸出,則需要將其更新為捕獲 sys.stderr。

  • str.startswith()str.endswith() 方法在找到空字串且索引完全超出範圍時不再返回 True。(由 Serhiy Storchaka 在 bpo-24284 中貢獻。)

  • inspect.getdoc() 函式現在返回從基類繼承的文件字串。如果繼承的文件是適當的,則不再需要重複文件字串。要抑制繼承的字串,必須指定空字串(或者可以填充文件)。此更改會影響 pydoc 模組和 help() 函式的輸出。(由 Serhiy Storchaka 在 bpo-15582 中貢獻。)

  • 巢狀的 functools.partial() 呼叫現在被扁平化。如果您依賴於以前的行為,您現在可以向 functools.partial() 物件新增屬性,或者您可以建立 functools.partial() 的子類。(由 Alexander Belopolsky 在 bpo-7830 中貢獻。)

C API 的變化

  • 已移除 (非公共) PyMemoryViewObject 結構中未文件化的 format 成員。所有依賴 memoryobject.h 中相關部分的擴充套件都必須重建。

  • PyMemAllocator 結構已重新命名為 PyMemAllocatorEx,並添加了一個新的 calloc 欄位。

  • 移除了洩漏引用的未文件化宏 PyObject_REPR()。在類似 PyUnicode_FromFormat() 的函式中使用格式字元 %R 來格式化物件的 repr()。(由 Serhiy Storchaka 在 bpo-22453 中貢獻。)

  • 由於缺少 __module__ 屬性會破壞 pickling 和內省,因此現在對於沒有 __module__ 屬性的內建型別會引發廢棄警告。這在將來會是一個 AttributeError。(由 Serhiy Storchaka 在 bpo-20204 中貢獻。)

  • 作為 PEP 492 實現的一部分,PyTypeObjecttp_reserved 插槽被 tp_as_async 插槽取代。有關新型別、結構和函式,請參閱 協程物件

Python 3.5.4 中的顯著變化

新的 make regen-all 構建目標

為了簡化交叉編譯,並確保 CPython 可以可靠地編譯而無需現有 Python 版本,基於 autotools 的構建系統不再嘗試根據檔案修改時間隱式重新編譯生成的檔案。

相反,已新增新的 make regen-all 命令,以便在需要時強制重新生成這些檔案(例如,在基於預生成版本構建了初始版本的 Python 之後)。

還定義了更具選擇性的重新生成目標——有關詳細資訊,請參閱 Makefile.pre.in

(由 Victor Stinner 在 bpo-23404 中貢獻。)

3.5.4 版本新增。

移除 make touch 構建目標

以前用於透過更新生成檔案的修改時間來請求隱式重新生成生成檔案的 make touch 構建目標已移除。

它已被新的 make regen-all 目標取代。

(由 Victor Stinner 在 bpo-23404 中貢獻。)

3.5.4 版本更改。