Python 3.8 有什么新變化
轉 https://docs.python.org/zh-cn/3.8/whatsnew/3.8.html
- 編者
-
Raymond Hettinger
本文解釋了 Python 3.8 相比 3.7 的新增特性。 完整的詳情可參閱 更新日志。
Python 3.8已於2019年10月14日發布。
摘要 - 發布重點
新的特性
賦值表達式
新增的語法 := 可在表達式內部為變量賦值。 它被昵稱為“海象運算符”因為它很像是 海象的眼睛和長牙。
在這個示例中,賦值表達式可以避免調用 len() 兩次:
if (n := len(a)) > 10: print(f"List is too long ({n} elements, expected <= 10)")
類似的益處還可出現在正則表達式匹配中需要使用兩次匹配對象的情況中,一次檢測用於匹配是否發生,另一次用於提取子分組:
discount = 0.0 if (mo := re.search(r'(\d+)% discount', advertisement)): discount = float(mo.group(1)) / 100.0
此運算符也適用於配合 while 循環計算一個值來檢測循環是否終止,而同一個值又在循環體中再次被使用的情況:
# Loop over fixed length blocks
while (block := f.read(256)) != '': process(block)
另一個值得介紹的用例出現於列表推導式中,在篩選條件中計算一個值,而同一個值又在表達式中需要被使用:
[clean_name.title() for name in names if (clean_name := normalize('NFC', name)) in allowed_names]
請盡量將海象運算符的使用限制在清晰的場合中,以降低復雜性並提升可讀性。
請參閱 PEP 572 了解詳情。
(由 Morehouse 在 bpo-35224 中貢獻。)
僅限位置形參
新增了一個函數形參語法 / 用來指明某些函數形參必須使用僅限位置而非關鍵字參數的形式。 這種標記語法與通過 help() 所顯示的使用 Larry Hastings 的 Argument Clinic 工具標記的 C 函數相同。
在下面的例子中,形參 a 和 b 為僅限位置形參,c 或 d 可以是位置形參或關鍵字形參,而 e 或 f 要求為關鍵字形參:
def f(a, b, /, c, d, *, e, f): print(a, b, c, d, e, f)
以下均為合法的調用:
f(10, 20, 30, d=40, e=50, f=60)
但是,以下均為不合法的調用:
f(10, b=20, c=30, d=40, e=50, f=60) # b cannot be a keyword argument f(10, 20, 30, 40, 50, f=60) # e must be a keyword argument
這種標記形式的一個用例是它允許純 Python 函數完整模擬現有的用 C 代碼編寫的函數的行為。 例如,內置的 pow() 函數不接受關鍵字參數:
def pow(x, y, z=None, /): "Emulate the built in pow() function" r = x ** y return r if z is None else r%z
另一個用例是在不需要形參名稱時排除關鍵字參數。 例如,內置的 len() 函數的簽名為 len(obj, /)。 這可以排除如下這種笨拙的調用形式:
len(obj='hello') # The "obj" keyword argument impairs readability
另一個益處是將形參標記為僅限位置形參將允許在未來修改形參名而不會破壞客戶的代碼。 例如,在 statistics 模塊中,形參名 dist 在未來可能被修改。 這使得以下函數描述成為可能:
def quantiles(dist, /, *, n=4, method='exclusive') ...
由於在 / 左側的形參不會被公開為可用關鍵字,其他形參名仍可在 **kwargs 中使用:
>>> def f(a, b, /, **kwargs): ... print(a, b, kwargs) ... >>> f(10, 20, a=1, b=2, c=3) # a and b are used in two ways 10 20 {'a': 1, 'b': 2, 'c': 3}
這極大地簡化了需要接受任意關鍵字參數的函數和方法的實現。 例如,以下是一段摘自 collections 模塊的代碼:
class Counter(dict): def __init__(self, iterable=None, /, **kwds): # Note "iterable" is a possible keyword argument
請參閱 PEP 570 了解詳情。
(由 Pablo Galindo 在 bpo-36540 中貢獻。)
用於已編譯字節碼文件的並行文件系統緩存
新增的 PYTHONPYCACHEPREFIX 設置 (也可使用 -X pycache_prefix) 可將隱式的字節碼緩存配置為使用單獨的並行文件系統樹,而不是默認的每個源代碼目錄下的 __pycache__ 子目錄。
緩存的位置會在 sys.pycache_prefix 中報告 (None 表示默認位置即 __pycache__ 子目錄)。
(由 Carl Meyer 在 bpo-33499 中貢獻。)
調試構建使用與發布構建相同的 ABI
Python 現在不論是以發布模式還是調試模式進行構建都將使用相同的 ABI。 在 Unix 上,當 Python 以調試模式構建時,現在將可以加載以發布模式構建的 C 擴展和使用穩定版 ABI 構建的 C 擴展。
發布構建和調試構建現在都是 ABI 兼容的:定義 Py_DEBUG 宏不會再啟用 Py_TRACE_REFS 宏,它引入了唯一的 ABI 不兼容性。 Py_TRACE_REFS 宏添加了 sys.getobjects() 函數和 PYTHONDUMPREFS 環境變量,它可以使用新的 ./configure --with-trace-refs 構建選項來設置。 (由 Victor Stinner 在 bpo-36465 中貢獻。)
在 Unix 上,C 擴展不會再被鏈接到 libpython,但 Android 和 Cygwin 例外。 現在靜態鏈接的 Python 將可以加載使用共享庫 Python 構建的 C 擴展。 (由 Victor Stinner 在 bpo-21536 中貢獻。)
在 Unix 上,當 Python 以調試模式構建時,導入操作現在也會查找在發布模式下編譯的 C 擴展以及使用穩定版 ABI 編譯的 C 擴展。 (由 Victor Stinner 在 bpo-36722 中貢獻。)
要將 Python 嵌入到一個應用中,必須將新增的 --embed 選項傳給 python3-config --libs --embed 以獲得 -lpython3.8 (將應用鏈接到 libpython)。 要同時支持 3.8 和舊版本,請先嘗試 python3-config --libs --embed 並在此命令失敗時回退到 python3-config --libs (即不帶 --embed)。
增加一個 pkg-config python-3.8-embed 模塊用來將 Python 嵌入到一個應用中: pkg-config python-3.8-embed --libs 包含 -lpython3.8。 要同時支持 3.8 和舊版本,請先嘗試 pkg-config python-X.Y-embed --libs 並在此命令失敗時回退到 pkg-config python-X.Y --libs (即不帶 --embed) (請將 X.Y 替換為 Python 版本號)。
另一方面,pkg-config python3.8 --libs 不再包含 -lpython3.8。 C 擴展不可被鏈接到 libpython (但 Android 和 Cygwin 例外,這兩者的情況由腳本處理);此改變是故意被設為向下不兼容的。 (由 Victor Stinner 在 bpo-36721 中貢獻。)
f-字符串支持 = 用於自動記錄表達式和調試文檔
增加 = 說明符用於 f-string。 形式為 f'{expr=}' 的 f-字符串將擴展表示為表達式文本,加一個等於號,再加表達式的求值結果。 例如:
>>> user = 'eric_idle' >>> member_since = date(1975, 7, 31) >>> f'{user=} {member_since=}' "user='eric_idle' member_since=datetime.date(1975, 7, 31)"
通常的 f-字符串格式說明符 允許更細致地控制所要顯示的表達式結果:
>>> delta = date.today() - member_since >>> f'{user=!s} {delta.days=:,d}' 'user=eric_idle delta.days=16,075'
= 說明符將輸出整個表達式,以便詳細演示計算過程:
>>> print(f'{theta=} {cos(radians(theta))=:.3f}') theta=30 cos(radians(theta))=0.866
(由 Eric V. Smith 和 Larry Hastings 在 bpo-36817 中貢獻。)
PEP 578: Python 運行時審核鈎子
此 PEP 添加了審核鈎子和已驗證開放鈎子。 兩者在 Python 與本機代碼中均可用。允許以純 Python 代碼編寫的應用和框架利用額外的通知,同時允許嵌入開發人員或系統管理員部署始終啟用審核的 Python 版本。
請參閱 PEP 578 了解詳情。
PEP 587: Python 初始化配置
PEP 587 增加了一個新的 C API 用來配置 Python 初始化,提供對整個配置過程的更細致控制以及更好的錯誤報告。
新的結構:
新的函數:
此 PEP 還為這些內部結構添加了 _PyRuntimeState.preconfig (PyPreConfig 類型) 和 PyInterpreterState.config (PyConfig 類型) 字段。 PyInterpreterState.config 成為新的引用配置,替代全局配置變量和其他私有變量。
請參閱 Python 初始化配置 獲取詳細文檔。
請參閱 PEP 587 了解詳情。
(由 Victor Stinner 在 bpo-36763 中貢獻。)
其他語言特性修改
-
在之前版本中
continue語句不允許在finally子句中使用,這是因為具體實現存在一個問題。 在 Python 3.8 中此限制已被取消。 (由 Serhiy Storchaka 在 bpo-32489 中貢獻。) -
bool,int和fractions.Fraction類型現在都有一個as_integer_ratio()方法,與float和decimal.Decimal中的已有方法類似。 這個微小的 API 擴展使得numerator, denominator = x.as_integer_ratio()這樣的寫法在多種數字類型上通用成為可能。 (由 Lisa Roach 在 bpo-33073 和 Raymond Hettinger 在 bpo-37819 中貢獻。) -
int,float和complex的構造器現在會使用__index__()特殊方法,如果該方法可用而對應的方法 method__int__(),__float__()或__complex__()方法不可用的話。 (由 Serhiy Storchaka 在 bpo-20092 中貢獻。) -
添加
\N{name}轉義符在正則表達式中的支持:>>> notice = 'Copyright © 2019' >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})') >>> int(copyright_year_pattern.search(notice).group(1)) 2019(由 Jonathan Eunice 和 Serhiy Storchaka 在 bpo-30688 中貢獻。)
-
現在 dict 和 dictview 可以使用
reversed()按插入順序反向迭代。 (由 Rémi Lapeyre 在 bpo-33462 中貢獻。) -
在函數調用中允許使用的關鍵字名稱語法受到進一步的限制。 特別地,
f((keyword)=arg)不再被允許。 關鍵字參數賦值形式的左側絕不允許一般標識符以外的其他內容。 (由 Benjamin Peterson 在 bpo-34641 中貢獻。) -
在
yield和return語句中的一般可迭代對象解包不再要求加圓括號。 這使得 yield 和 return 的語法與正常的賦值語法更為一致:>>> def parse(family): lastname, *members = family.split() return lastname.upper(), *members >>> parse('simpsons homer marge bart lisa sally') ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'sally')(由 David Cuthbert 和 Jordan Chapman 在 bpo-32117 中貢獻。)
-
當類似
[(10, 20) (30, 40)]這樣在代碼中少了一個逗號時,編譯器將顯示SyntaxWarning並附帶更有幫助的提示。 這相比原來用TypeError來提示第一個元組是不可調用的更容易被理解。 (由 Serhiy Storchaka 在 bpo-15248 中貢獻。) -
datetime.date或datetime.datetime和datetime.timedelta對象之間的算術運算現在將返回相應子類的實例而不是基類的實例。 這也會影響到在具體實現中(直接或間接地)使用了datetime.timedelta算術運算的返回類型,例如astimezone()。 (由 Paul Ganssle 在 bpo-32417 中貢獻。) -
當 Python 解釋器通過 Ctrl-C (SIGINT) 被中斷並且所產生的
KeyboardInterrupt異常未被捕獲,Python 進程現在會通過一個 SIGINT 信號或是使得發起調用的進程能檢測到它是由 Ctrl-C 操作殺死的正確退出代碼來退出。 POSIX 和 Windows 上的終端會相應地使用此代碼在交互式會話中終止腳本。 (由 Google 的 Gregory P. Smith 在 bpo-1054041 中貢獻。) -
某些高級編程風格要求為現有的函數更新
types.CodeType對象。 由於代碼對象是不可變的,需要基於現有代碼對象模型創建一個新的代碼對象。 使用 19 個形參將會相當繁瑣。 現在,新的replace()方法使得通過少量修改的形參創建克隆對象成為可能。下面是一個修改
statistics.mean()函數來防止 data 形參被用作關鍵字參數的例子:>>> from statistics import mean >>> mean(data=[10, 20, 90]) 40 >>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1) >>> mean(data=[10, 20, 90]) Traceback (most recent call last): ... TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'(由 Victor Stinner 在 bpo-37032 中貢獻。)
-
對於整數,現在
pow()函數的三參數形式在底數與模數不可約的情況下允許指數為負值。 隨后它會在指數為-1時計算底數的模乘逆元,並對其他負指數計算反模的適當冪次。 例如,要計算 38 模 137 的 模乘逆元 則可寫為:>>> pow(38, -1, 137) 119 >>> 119 * 38 % 137 1模乘逆元在求解 線性丟番圖方程 會被用到。 例如,想要求出
4258𝑥 + 147𝑦 = 369的整數解,首先應重寫為4258𝑥 ≡ 369 (mod 147)然后求解:>>> x = 369 * pow(4258, -1, 147) % 147 >>> y = (4258 * x - 369) // -147 >>> 4258 * x + 147 * y 369(由 Mark Dickinson 在 bpo-36027 中貢獻。)
-
字典推導式已與字典字面值實現同步,會先計算鍵再計算值:
>>> # Dict comprehension >>> cast = {input('role? '): input('actor? ') for i in range(2)} role? King Arthur actor? Chapman role? Black Knight actor? Cleese >>> # Dict literal >>> cast = {input('role? '): input('actor? ')} role? Sir Robin actor? Eric Idle對執行順序的保證對賦值表達式來說很有用,因為在鍵表達式中賦值的變量將可在值表達式中被使用:
>>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald'] >>> {(n := normalize('NFC', name)).casefold() : n for name in names} {'martin von löwis': 'Martin von Löwis', 'łukasz langa': 'Łukasz Langa', 'walter dörwald': 'Walter Dörwald'}(由 Jörn Heissler 在 bpo-35224 中貢獻。)
-
object.__reduce__()方法現在可返回長度為二至六個元素的元組。 之前的上限為五個。 新增的第六個可選元素是簽名為(obj, state)的可調用對象。 這樣就允許直接控制特定對象的狀態更新。 如果元素值不為 None,該可調用對象將優先於對象的__setstate__()方法。 (由 Pierre Glaser 和 Olivier Grisel 在 bpo-35900 中貢獻。)
新增模塊
-
新增的
importlib.metadata模塊提供了從第三方包讀取元數據的(臨時)支持。 例如,它可以提取一個已安裝軟件包的版本號、入口點列表等等:>>> # Note following example requires that the popular "requests" >>> # package has been installed. >>> >>> from importlib.metadata import version, requires, files >>> version('requests') '2.22.0' >>> list(requires('requests')) ['chardet (<3.1.0,>=3.0.2)'] >>> list(files('requests'))[:5] [PackagePath('requests-2.22.0.dist-info/INSTALLER'), PackagePath('requests-2.22.0.dist-info/LICENSE'), PackagePath('requests-2.22.0.dist-info/METADATA'), PackagePath('requests-2.22.0.dist-info/RECORD'), PackagePath('requests-2.22.0.dist-info/WHEEL')](由 Barry Warsaw 和 Jason R. Coombs 在 bpo-34632 中貢獻)。
改進的模塊
ast
AST 節點現在具有 end_lineno 和 end_col_offset 屬性,它們給出節點結束的精確位置。 (這只適用於具有 lineno 和 col_offset 屬性的節點。)
新增函數 ast.get_source_segment() 返回指定 AST 節點的源代碼。
(由 Ivan Levkivskyi 在 bpo-33416 中貢獻。)
ast.parse() 函數具有一些新的旗標:
-
type_comments=True導致其返回與特定 AST 節點相關聯的 PEP 484 和 PEP 526 類型注釋文本; -
mode='func_type'可被用於解析 PEP 484 "簽名類型注釋" (為函數定義 AST 節點而返回); -
feature_version=(3, N)允許指定一個更早的 Python 3 版本。 例如,feature_version=(3, 4)將把async和await視為非保留字。
(由 Guido van Rossum 在 bpo-35766 中貢獻。)
asyncio
asyncio.run() 已經從暫定狀態晉級為穩定 API。 此函數可被用於執行一個 coroutine 並返回結果,同時自動管理事件循環。 例如:
import asyncio async def main(): await asyncio.sleep(0) return 42 asyncio.run(main())
這 大致 等價於:
import asyncio async def main(): await asyncio.sleep(0) return 42 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(main()) finally: asyncio.set_event_loop(None) loop.close()
The actual implementation is significantly more complex. Thus, asyncio.run() should be the preferred way of running asyncio programs.
(由 Yury Selivanov 在 bpo-32314 中貢獻。)
運行 python -m asyncio 將啟動一個原生異步 REPL。 這允許快速體驗具有最高層級 await 的代碼。 這時不再需要直接調用 asyncio.run(),因為此操作會在每次發起調用時產生一個新事件循環:
$ python -m asyncio
asyncio REPL 3.8.0
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(10, result='hello')
hello
(由 Yury Selivanov 在 bpo-37028 中貢獻。)
The exception asyncio.CancelledError now inherits from BaseException rather than Exception. (Contributed by Yury Selivanov in bpo-32528.)
在 Windows 上,現在默認的事件循環為 ProactorEventLoop。 (由 Victor Stinner 在 bpo-34687 中貢獻。)
ProactorEventLoop 現在也支持 UDP。 (由 Adam Meily 和 Andrew Svetlov 在 bpo-29883 中貢獻。)
ProactorEventLoop 現在可通過 KeyboardInterrupt ("CTRL+C") 來中斷。 (由 Vladimir Matveev 在 bpo-23057 中貢獻。)
Added asyncio.Task.get_coro() for getting the wrapped coroutine within an asyncio.Task. (Contributed by Alex Grönholm in bpo-36999.)
Asyncio tasks can now be named, either by passing the name keyword argument to asyncio.create_task() or the create_task() event loop method, or by calling the set_name() method on the task object. The task name is visible in the repr() output of asyncio.Task and can also be retrieved using the get_name() method. (Contributed by Alex Grönholm in bpo-34270.)
Added support for Happy Eyeballs to asyncio.loop.create_connection(). To specify the behavior, two new parameters have been added: happy_eyeballs_delay and interleave. The Happy Eyeballs algorithm improves responsiveness in applications that support IPv4 and IPv6 by attempting to simultaneously connect using both. (Contributed by twisteroid ambassador in bpo-33530.)
builtins
內置的 compile() 已改進為可接受 ast.PyCF_ALLOW_TOP_LEVEL_AWAIT 旗標。 當傳入此新旗標時,compile() 將允許通常被視為無效語法的最高層級 await, async for 和 async with 構造。 此后將可返回帶有 CO_COROUTINE 旗標的異步代碼對象。 (由 Matthias Bussonnier 在 bpo-34616 中貢獻。)
collections
collections.namedtuple() 的 _asdict() 方法現在將返回 dict 而不是 collections.OrderedDict。 此項更改是由於普通字典自 Python 3.7 起已保證具有確定的元素順序。 如果還需要 OrderedDict 的額外特性,建議的解決方案是將結果轉換為需要的類型: OrderedDict(nt._asdict())。 (由 Raymond Hettinger 在 bpo-35864 中貢獻。)
cProfile
cProfile.Profile 類現在可被用作上下文管理器。 在運行時對一個代碼塊實現性能分析:
import cProfile with cProfile.Profile() as profiler: # code to be profiled ...
(由 Scott Sanderson 在 bpo-29235 中貢獻。)
csv
The csv.DictReader now returns instances of dict instead of a collections.OrderedDict. The tool is now faster and uses less memory while still preserving the field order. (Contributed by Michael Selik in bpo-34003.)
curses
添加了一個新變量用於保存下層 ncurses 庫的結構版信息: ncurses_version。 (由 Serhiy Storchaka 在 bpo-31680 中貢獻。)
ctypes
在 Windows 上,CDLL 及其子類現在接受 winmode 形參來指定用於底層 LoadLibraryEx 調用的旗標。 默認旗標被設為僅加載來自可信任位置的 DLL 依賴項,包括 DLL 的存放路徑(如果加載初始 DLL 時使用了完整或部分路徑)以及通過 add_dll_directory() 添加的路徑。 (由 Steve Dower 在 bpo-36085 中貢獻。)
datetime
添加了新的替代構造器 datetime.date.fromisocalendar() 和 datetime.datetime.fromisocalendar(),它們分別基於 ISO 年份、周序號和周內日序號來構造 date 和 datetime 對象;這兩者分別是其所對應類中 isocalendar 方法的逆操作。 (由 Paul Ganssle 在 bpo-36004 中貢獻。)
functools
functools.lru_cache() 現在可直接作為裝飾器而不是作為返回裝飾器的函數。 因此這兩種寫法現在都被支持:
@lru_cache
def f(x): ... @lru_cache(maxsize=256) def f(x): ...
(由 Raymond Hettinger 在 bpo-36772 中貢獻。)
添加了新的 functools.cached_property() 裝飾器,用於在實例生命周期內緩存的已計算特征屬性。
import functools import statistics class Dataset: def __init__(self, sequence_of_numbers): self.data = sequence_of_numbers @functools.cached_property def variance(self): return statistics.variance(self.data)
(由 Carl Meyer 在 bpo-21145 中貢獻)
添加了新的 functools.singledispatchmethod() 裝飾器可使用 single dispatch 將方法轉換為 泛型函數:
from functools import singledispatchmethod from contextlib import suppress class TaskManager: def __init__(self, tasks): self.tasks = list(tasks) @singledispatchmethod def discard(self, value): with suppress(ValueError): self.tasks.remove(value) @discard.register(list) def _(self, tasks): targets = set(tasks) self.tasks = [x for x in self.tasks if x not in targets]
(由 Ethan Smith 在 bpo-32380 中貢獻)
gc
get_objects() 現在能接受一個可選的 generation 形參來指定一個用於獲取對象的生成器。 (由 Pablo Galindo 在 bpo-36016 中貢獻。)
gettext
添加了 pgettext() 及其變化形式。 (由 Franz Glasner, Éric Araujo 和 Cheryl Sabella 在 bpo-2504 中貢獻。)
gzip
添加 mtime 形參到 gzip.compress() 用於可重現的輸出。 (由 Guo Ci Teo 在 bpo-34898 中貢獻。)
對於特定類型的無效或已損壞 gzip 文件現在將引發 BadGzipFile 而不是 OSError。 (由 Filip Gruszczyński, Michele Orrù 和 Zackery Spytz 在 bpo-6584 中貢獻。)
IDLE 與 idlelib
超過 N 行(默認值為 50)的輸出將被折疊為一個按鈕。 N 可以在 Settings 對話框的 General 頁的 PyShell 部分中進行修改。 數量較少但是超長的行可以通過在輸出上右擊來折疊。 被折疊的輸出可通過雙擊按鈕來展開,或是通過右擊按鈕來放入剪貼板或是單獨的窗口。 (由 Tal Einat 在 bpo-1529353 中貢獻。)
在 Run 菜單中增加了 "Run Customized" 以使用自定義設置來運行模塊。 輸入的任何命令行參數都會被加入 sys.argv。 它們在下次自定義運行時會再次顯示在窗體中。 用戶也可以禁用通常的 Shell 主模塊重啟。 (由 Cheryl Sabella, Terry Jan Reedy 等人在 bpo-5680 和 bpo-37627 中貢獻。)
在 IDLE 編輯器窗口中增加了可選的行號。 窗口打開時默認不顯示行號,除非在配置對話框的 General 選項卡中特別設置。 已打開窗口中的行號可以在 Options 菜單中顯示和隱藏。 (由 Tal Einat 和 Saimadhav Heblikar 在 bpo-17535 中貢獻。)
現在會使用 OS 本機編碼格式在 Python 字符串和 Tcl 對象間進行轉換。 這允許在 IDLE 中處理 emoji 和其他非 BMP 字符。 這些字符將可被顯示或是從剪貼板復制和粘貼。 字符串從 Tcl 到 Python 的來回轉換現在不會再發生失敗。 (過去八年有許多人都為此付出過努力,問題最終由 Serhiy Storchaka 在 bpo-13153 中解決。)
上述修改已被反向移植到 3.7 維護發行版中。
inspect
inspect.getdoc() 函數現在可以找到 __slots__ 的文檔字符串,如果該屬性是一個元素值為文檔字符串的 dict 的話。 這提供了類似於目前已有的 property(), classmethod() 和 staticmethod() 等函數的文檔選項:
class AudioClip: __slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place', 'duration': 'in seconds, rounded up to an integer'} def __init__(self, bit_rate, duration): self.bit_rate = round(bit_rate / 1000.0, 1) self.duration = ceil(duration)
(由 Raymond Hettinger 在 bpo-36326 中貢獻。)
io
在開發模式 (-X env) 和調試構建中,io.IOBase 終結器現在會在 close() 方法失敗時將異常寫入日志。 發生的異常在發布構建中默認會被靜默忽略。 (由 Victor Stinner 在 bpo-18748 中貢獻。)
itertools
itertools.accumulate() 函數增加了可選的 initial 關鍵字參數用來指定一個初始值:
>>> from itertools import accumulate >>> list(accumulate([10, 5, 30, 15], initial=1000)) [1000, 1010, 1015, 1045, 1060]
(由 Lisa Roach 在 bpo-34659 中貢獻。)
json.tool
添加選項 --json-lines 用於將每個輸入行解析為單獨的 JSON 對象。 (由 Weipeng Hong 在 bpo-31553 中貢獻。)
logging
Added a force keyword argument to logging.basicConfig() When set to true, any existing handlers attached to the root logger are removed and closed before carrying out the configuration specified by the other arguments.
這解決了一個長期存在的問題。 當一個日志處理器或 basicConfig() 被調用時,對 basicConfig() 的后續調用會被靜默地忽略。 這導致使用交互提示符或 Jupyter 筆記本更新、試驗或講解各種日志配置選項變得相當困難。
(由 Raymond Hettinger 提議,由 Dong-hee Na 實現,並由 Vinay Sajip 在 bpo-33897 中完成審核。)
math
添加了新的函數 math.dist() 用於計算兩點之間的歐幾里得距離。 (由 Raymond Hettinger 在 bpo-33089 中貢獻。)
擴展了 math.hypot() 函數以便處理更多的維度。 之前它僅支持 2-D 的情況。 (由 Raymond Hettinger 在 bpo-33089 中貢獻。)
添加了新的函數 math.prod() 作為的 sum() 同類,該函數返回 'start' 值 (默認值: 1) 乘以一個數字可迭代對象的積:
>>> prior = 0.8 >>> likelihoods = [0.625, 0.84, 0.30] >>> math.prod(likelihoods, start=prior) 0.126
(由 Pablo Galindo 在 bpo-35606 中貢獻。)
添加了兩個新的組合函數 math.perm() 和 math.comb():
>>> math.perm(10, 3) # Permutations of 10 things taken 3 at a time 720 >>> math.comb(10, 3) # Combinations of 10 things taken 3 at a time 120
(由 Yash Aggarwal, Keller Fuchs, Serhiy Storchaka 和 Raymond Hettinger 在 bpo-37128, bpo-37178 和 bpo-35431 中貢獻。)
添加了一個新函數 math.isqrt() 用於計算精確整數平方根而無需轉換為浮點數。 該新函數支持任意大整數。 它的執行速度比 floor(sqrt(n)) 快但是比 math.sqrt() 慢:
>>> r = 650320427 >>> s = r ** 2 >>> isqrt(s - 1) # correct 650320426 >>> floor(sqrt(s - 1)) # incorrect 650320427
(由 Mark Dickinson 在 bpo-36887 中貢獻。)
函數 math.factorial() 不再接受非整數類參數。 (由 Pablo Galindo 在 bpo-33083 中貢獻。)
multiprocessing
添加了新的 multiprocessing.shared_memory 模塊。 (由 Davin Potts 在 bpo-35813 中貢獻。)
在macOS上,現在默認使用的啟動方式是*spawn*啟動方式。 (由 Victor Stinner 在 bpo-33725 中貢獻。)
os
在 Windows 上添加了新函數 add_dll_directory() 用於在導入擴展模塊或使用 ctypes 加載 DLL 時為本機依賴提供額外搜索路徑 。 (由 Steve Dower 在 bpo-36085 中貢獻。)
添加了新的 os.memfd_create() 函數用於包裝 memfd_create() 系統調用。 (由 Zackery Spytz 和 Christian Heimes 在 bpo-26836 中貢獻。)
在 Windows 上,大部分用於處理重解析點,(包括符號鏈接和目錄連接)的手動邏輯已被委托給操作系統。 特別地,os.stat() 現在將會遍歷操作系統所支持的任何內容,而 os.lstat() 將只打開被標識為“名稱代理”的重解析點,而其要由 os.stat() 打開其他的重解析點。 在所有情況下,stat_result.st_mode 將只為符號鏈接而非其他種類的重解析點設置 S_IFLNK。 要標識其他種類的重解析點,請檢查新的 stat_result.st_reparse_tag 屬性。
在 Windows 上,os.readlink() 現在能夠讀取目錄連接。 請注意 islink() 會對目錄連接返回 False,因此首先檢查 islink 的代碼將連續把連接視為目錄,而會處理 os.readlink() 所引發錯誤的代碼現在會把連接視為鏈接。
(由 Steve Dower 在 bpo-37834 中貢獻。)
os.path
返回布爾值結果的 os.path 函數例如 exists(), lexists(), isdir(), isfile(), islink(), 以及 ismount() 現在對於包含在 OS 層級無法表示的字符或字節的路徑將會返回 False 而不是引發 ValueError 或其子類 UnicodeEncodeError 和 UnicodeDecodeError。 (由 Serhiy Storchaka 在 bpo-33721 中貢獻。)
expanduser() 在 Windows 上現在改用 USERPROFILE 環境變量而不再使用 HOME,后者通常不會為一般用戶賬戶設置。 (由 Anthony Sottile 在 bpo-36264 中貢獻。)
isdir() on Windows no longer returns True for a link to a non-existent directory.
realpath() 在 Windows 上現在會識別重解析點,包括符號鏈接和目錄連接。
(由 Steve Dower 在 bpo-37834 中貢獻。)
pathlib
返回布爾值結果的 pathlib.Path 方法例如 exists(), is_dir(), is_file(), is_mount(), is_symlink(), is_block_device(), is_char_device(), is_fifo(), is_socket() 現在對於包含在 OS 層級無法表示的字符或字節的路徑將會返回 False 而不是引發 ValueError 或其子類 UnicodeEncodeError。 (由 Serhiy Storchaka 在 bpo-33721 中貢獻。)
添加了 pathlib.Path.link_to() 用於創建指向某個路徑的硬鏈接。 (由 Joannah Nanjekye 在 bpo-26978 中貢獻。)
pickle
pickle 擴展子類化針對 C 優化的 Pickler 現在可通過定義特殊的 reducer_override() 方法來重載函數和類的封存邏輯。 (由 Pierre Glaser 和 Olivier Grisel 在 bpo-35900 中貢獻。)
plistlib
添加了新的 plistlib.UID 並啟動了對讀取和寫入經過 NSKeyedArchiver 編碼的二進制 plists 的支持。 (由 Jon Janzen 在 bpo-26707 中貢獻。)
pprint
The pprint module added a sort_dicts parameter to several functions. By default, those functions continue to sort dictionaries before rendering or printing. However, if sort_dicts is set to false, the dictionaries retain the order that keys were inserted. This can be useful for comparison to JSON inputs during debugging.
In addition, there is a convenience new function, pprint.pp() that is like pprint.pprint() but with sort_dicts defaulting to False:
>>> from pprint import pprint, pp >>> d = dict(source='input.txt', operation='filter', destination='output.txt') >>> pp(d, width=40) # Original order {'source': 'input.txt', 'operation': 'filter', 'destination': 'output.txt'} >>> pprint(d, width=40) # Keys sorted alphabetically {'destination': 'output.txt', 'operation': 'filter', 'source': 'input.txt'}
(由 Rémi Lapeyre 在 bpo-30670 中貢獻。)
py_compile
py_compile.compile() 現在支持靜默模式。 (由 Joannah Nanjekye 在 bpo-22640 中貢獻。)
shlex
新增了 shlex.join() 函數作為 shlex.split() 的逆操作。 (由 Bo Bayles 在 bpo-32102 中貢獻。)
shutil
shutil.copytree() 現在接受新的 dirs_exist_ok 關鍵字參數。 (由 Josh Bronson 在 bpo-20849 中貢獻。)
shutil.make_archive() 現在對新的歸檔默認使用 modern pax (POSIX.1-2001) 格式以提升可移植性和標准一致性,此特性繼承自對 tarfile 模塊的相應更改。 (由 C.A.M. Gerlach 在 bpo-30661 中貢獻。)
shutil.rmtree() 在 Windows 上現在會移除目錄連接而不會遞歸地先移除其中的內容。 (由 Steve Dower 在 bpo-37834 中貢獻。)
socket
添加了便捷的 create_server() 和 has_dualstack_ipv6() 函數以自動化在創建服務器套接字時通常情況下所必須的任務,包括在同一套接字中同時接受 IPv4 和 IPv6 連接。 (由 Giampaolo Rodolà 在 bpo-17561 中貢獻。)
socket.if_nameindex(), socket.if_nametoindex() 和 socket.if_indextoname() 函數已經在 Windows 上實現。 (由 Zackery Spytz 在 bpo-37007 中貢獻。)
ssl
增加了 post_handshake_auth 和 verify_client_post_handshake() 分別啟用和初始化 TLS 1.3 握手后驗證。 (由 Christian Heimes 在 bpo-34670 中貢獻。)
statistics
添加了 statistics.fmean() 作為 statistics.mean() 的更快速的浮點數版版本。 (由 Raymond Hettinger 和 Steven D'Aprano 在 bpo-35904 中貢獻。)
添加了 statistics.geometric_mean() (由 Raymond Hettinger 在 bpo-27181 中貢獻。)
添加了 statistics.multimode() 用於返回最常見值的列表。 (由 Raymond Hettinger 在 bpo-35892 中貢獻。)
添加了 statistics.quantiles() 用於將數據或分布划分為多個等概率區間(例如四分位、十分位或百分位)。 (由 Raymond Hettinger 在 bpo-36546 中貢獻。)
添加了 statistics.NormalDist 用於創建和操縱隨機變量的正態分布。 (由 Raymond Hettinger 在 bpo-36018 中貢獻。)
>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14]) >>> temperature_feb.mean 6.0 >>> temperature_feb.stdev 6.356099432828281 >>> temperature_feb.cdf(3) # Chance of being under 3 degrees 0.3184678262814532 >>> # Relative chance of being 7 degrees versus 10 degrees >>> temperature_feb.pdf(7) / temperature_feb.pdf(10) 1.2039930378537762 >>> el_niño = NormalDist(4, 2.5) >>> temperature_feb += el_niño # Add in a climate effect >>> temperature_feb NormalDist(mu=10.0, sigma=6.830080526611674) >>> temperature_feb * (9/5) + 32 # Convert to Fahrenheit NormalDist(mu=50.0, sigma=12.294144947901014) >>> temperature_feb.samples(3) # Generate random samples [7.672102882379219, 12.000027119750287, 4.647488369766392]
sys
添加了新的 sys.unraisablehook() 函數,可被重載以便控制如何處理“不可引發的異常”。 它會在發生了一個異常但 Python 沒有辦法處理時被調用。 例如,當一個析構器在垃圾回收時 (gc.collect()) 所引發的異常。 (由 Victor Stinner 在 bpo-36829 中貢獻。)
tarfile
tarfile 模塊現在對新的歸檔默認使用 modern pax (POSIX.1-2001) 格式而不再是之前的 GNU 專屬格式。 這通過標准化和可擴展格式的統一編碼 (UTF-8) 提升了跨平台可移植性,還提供了其他一些益處。 (由 C.A.M. Gerlach 在 bpo-36268 中貢獻。)
threading
添加了新的 threading.excepthook() 函數用來處理未捕獲的 threading.Thread.run() 異常。 它可被重載以便控制如何處理未捕獲的 threading.Thread.run() 異常。 (由 Victor Stinner 在 bpo-1230540 中貢獻。)
添加了新的 threading.get_native_id() 函數以及 threading.Thread 類的 native_id 屬性。 它們會返回內核所分配給當前線程的原生整數線程 ID。 此特性僅在特定平台上可用,參見 get_native_id 了解詳情。 (由 Jake Tesler 在 bpo-36084 中貢獻。)
tokenize
當提供不帶末尾新行的輸入時,tokenize 模塊現在會隱式地添加 NEWLINE 形符。 此行為現在已與 C 詞法分析器的內部行為相匹配。 (由 Ammar Askar 在 bpo-33899 中貢獻。)
tkinter
在 tkinter.Spinbox 中添加了方法 selection_from(), selection_present(), selection_range() 和 selection_to()。 (由 Juliette Monsel 在 bpo-34829 中貢獻。)
在 tkinter.Canvas 類中添加了方法 moveto()。 (由 Juliette Monsel 在 bpo-23831 中貢獻。)
tkinter.PhotoImage 類現在具有 transparency_get() 和 transparency_set() 方法。 (由 Zackery Spytz 在 bpo-25451 中貢獻。)
time
為 macOS 10.12 添加了新的時鍾 CLOCK_UPTIME_RAW。 (由 Joannah Nanjekye 在 bpo-35702 中貢獻。)
typing
typing 模塊加入了一些新特性:
-
一個帶有鍵專屬類型的字典類型。 參見 PEP 589 和
typing.TypedDict。 TypedDict 只使用字符串作為鍵。 默認情況下每個鍵都要求提供。 指定 "total=False" 以允許鍵作為可選項:class Location(TypedDict, total=False): lat_long: tuple grid_square: str xy_coordinate: tuple -
Literal 類型。 參見 PEP 586 和
typing.Literal。 Literal 類型指明一個形參或返回值被限定為一個或多個特定的字面值:def get_status(port: int) -> Literal['connected', 'disconnected']: ... -
"Final" 變量、函數、方法和類。 參見 PEP 591,
typing.Final和typing.final()。 final 限定符會指示靜態類型檢查器限制進行子類化、重載或重新賦值:pi: Final[float] = 3.1415926536 -
協議定義。 參見 PEP 544,
typing.Protocol和typing.runtime_checkable()。 簡單的 ABC 例如typing.SupportsInt現在是Protocol的子類。 -
新的協議類
typing.SupportsIndex。 -
新的函數
typing.get_origin()和typing.get_args()。
unicodedata
unicodedata 模塊現在已升級為使用 Unicode 12.1.0 發布版。
新的函數 is_normalized() 可被用來驗證字符串是否為特定正規形式,通常會比實際進行字符串正規化要快得多。 (由 Max Belanger, David Euresti 和 Greg Price 在 bpo-32285 和 bpo-37966 中貢獻。)
unittest
添加了 AsyncMock 以支持異步版本的 Mock。 同時也添加了相應的斷言函數用於測試。 (由 Lisa Roach 在 bpo-26467 中貢獻。)
unittest 添加了 addModuleCleanup() 和 addClassCleanup() 以支持對 setUpModule() 和 setUpClass() 進行清理。 (由 Lisa Roach 在 bpo-24412 中貢獻。)
一些模擬斷言函數現在也會在失敗時打印一個實際調用列表。 (由 Petter Strandmark 在 bpo-35047 中貢獻。)
unittest 模塊已支持通過 unittest.IsolatedAsyncioTestCase 來使用協程作為測試用例。 (由 Andrew Svetlov 在 bpo-32972 中貢獻。)
示例:
import unittest class TestRequest(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self): self.connection = await AsyncConnection() async def test_get(self): response = await self.connection.get("https://example.com") self.assertEqual(response.status_code, 200) async def asyncTearDown(self): await self.connection.close() if __name__ == "__main__": unittest.main()
venv
現在 venv 在所有平台上都會包含 Activate.ps1 腳本用於在 PowerShell Core 6.1 下激活虛擬環境。 (由 Brett Cannon 在 bpo-32718 中貢獻。)
weakref
由 weakref.proxy() 返回的代理對象現在除其他算術運算符外也支持矩陣乘法運算符 @ 和 @=。 (由 Mark Dickinson 在 bpo-36669 中貢獻。)
xml
作為對 DTD 和外部實體檢索的緩解,在默認情況下 xml.dom.minidom 和 xml.sax 模塊不再處理外部實體。 (由 Christian Heimes 在 bpo-17239 中貢獻。)
xml.etree.ElementTree 模塊中的 .find*() 方法支持通配符搜索例如 {*}tag,此搜索會忽略命名空間以及返回給定命名空間中所有標簽的 {namespace}*。 (由 Stefan Behnel 在 bpo-28238 中貢獻。)
xml.etree.ElementTree 模塊提供了實現 C14N 2.0 的新函數 –xml.etree.ElementTree.canonicalize()。 (由 Stefan Behnel 在 bpo-13611 中貢獻。)
xml.etree.ElementTree.XMLParser 的目標對象可通過新的回調方法 start_ns() 和 end_ns() 來接受命名空間聲明事件。 此外,xml.etree.ElementTree.TreeBuilder 目標可被配置為處理有關注釋和處理指令事件以將它們包含在所生成的樹當中。 (由 Stefan Behnel 在 bpo-36676 和 bpo-36673 中貢獻。)
xmlrpc
xmlrpc.client.ServerProxy 現在支持可選的 headers 關鍵字參數作為隨同每次請求發送的 HTTP 標頭序列。 此特征的作用之一是使得從默認的基礎認證升級到更快速的會話認證成為可能。 (由 Cédric Krier 在 bpo-35153 中貢獻。)
性能優化
-
subprocess模塊現在能在某些情況下使用os.posix_spawn()函數以獲得更好的性能。 目前,它的使用僅限 macOS 和 Linux(使用 glibc 2.24 或更新版本),並要求滿足以下條件:-
close_fds 為假值;
-
preexec_fn, pass_fds, cwd 和 start_new_session 形參未設置;
-
executable 路徑包含一個目錄。
(由 Joannah Nanjekye 和 Victor Stinner 在 bpo-35537 中貢獻。)
-
-
shutil.copyfile(),shutil.copy(),shutil.copy2(),shutil.copytree()和shutil.move()在 Linux 和 macOS 上會使用平台專屬的 "fast-copy" 系統調用以提高效率。 "fast-copy" 意味着拷貝操作發生於內核中,從而避免在進行 "outfd.write(infd.read())" 等操作時使用 Python 中的用戶空間緩沖區。 在 Windows 上shutil.copyfile()會使用更大的默認緩沖區(1 MiB 而不是 16 KiB)並且使用基於memoryview()的shutil.copyfileobj()版本。 在同一分區內拷貝一個 512 MiB 文件的速度提升在 Linux 上約為 +26%,在 macOS 上為 +50%,在 Windows 上為 +40%。 此外還將消耗更少的 CPU 周期。 參見 依賴於具體平台的高效拷貝操作 一節。 (由 Giampaolo Rodolà 在 bpo-33671 中貢獻。) -
shutil.copytree()會根據其所用緩存的os.stat()值使用os.scandir()函數及所有拷貝函數。 拷貝一個包含 8000 文件的目錄的速度提升在 Linux 上約為 +9%,在 Windows 上為 +20%,對於 Windows SMB 共享目錄則為 +30%。 此外os.stat()系統調用的次數也減少了 38%,使得shutil.copytree()在網絡文件系統上會特別快速。 (由Giampaolo Rodolà 在 bpo-33695 中貢獻。) -
pickle模塊使用的默認協議現在為 Protocol 4,最早在 Python 3.4 中被引入。 它提供了比自 Python 3.0 起可用的 Protocol 3 更好的性能和更小的數據尺寸。 -
從
PyGC_Head移除了一個Py_ssize_t成員。 所有跟蹤 GC 的對象(例如 tuple, list, dict)大小減少了 4 或 8 字節。 (由 Inada Naoki 在 bpo-33597 中貢獻。) -
uuid.UUID現在會使用__slots__以減少內存足跡。 (由 Wouter Bolsterlee 和 Tal Einat 在 bpo-30977 中貢獻。) -
operator.itemgetter()的性能提升了 33%。 優化了參數處理,並為常見的在元組中單個非負整數索引的情況新增了一條快速路徑(這是標准庫中的典型用例)。 (由 Raymond Hettinger 在 bpo-35664 中貢獻。 -
加快了在
collections.namedtuple()中的字段查找。 它們現在的速度快了兩倍以上,成為 Python 中最快的實例變量查找形式。 (由 Raymond Hettinger, Pablo Galindo 和 Joe Jevnik, Serhiy Storchaka 在 bpo-32492 中貢獻。) -
如果輸入的可迭代對象的長度已知 (即輸入對象實現了
__len__),list構造器不會過度分配內部項緩沖區。 這使得所創建的列表資源占用平均減少了 12%。 (由 Raymond Hettinger 和 Pablo Galindo 在 bpo-33234 中貢獻。) -
類變量寫入速度加倍。 當一個非冗余屬性被更新時,之前存在一個更新 slots 的非必要調用。 (由 Stefan Behnel, Pablo Galindo Salgado, Raymond Hettinger, Neil Schemenauer, 和 Serhiy Storchaka 在 bpo-36012 中貢獻。)
-
減少了傳遞給許多內置函數和方法的參數轉換的開銷。 這使得某些簡單內置函數和方法的速度提升了 20--50%。 (由 Serhiy Storchaka 在 bpo-23867, bpo-35582 和 bpo-36127 中貢獻。)
-
LOAD_GLOBAL指令現在會使用新的 "per opcode cache" 機制。 它的速度現在提升了大約 40%。 (由 Yury Selivanov 和 Inada Naoki 在 bpo-26219 中貢獻。)
構建和 C API 的改變
-
默認的
sys.abiflags成為一個空字符串:pymalloc 的m旗標不再有意義(無論是否啟用 pymalloc 構建都是兼容 ABI 的)因此已被移除。 (由 Victor Stinner 在 bpo-36707 中貢獻。)改變的例子:
-
只會安裝
python3.8程序,不再有python3.8m程序。 -
只會安裝
python3.8-config腳本,不再有python3.8m-config腳本。 -
m旗標已經從動態庫文件名后綴中移除:包括標准庫中的擴展模塊以及第三方包所產生和安裝的模塊例如從 PyPI 下載的模塊。 以 Linux 為例,Python 3.7 的后綴.cpython-37m-x86_64-linux-gnu.so在 Python 3.8 中改為.cpython-38-x86_64-linux-gnu.so。
-
-
重新組織了所有頭文件以更好地區分不同種類的 API:
-
Include/*.h應為可移植的公有穩定版 C API。 -
Include/cpython/*.h應為 CPython 專屬的不穩定版 C API;公有 API,部分私有 API 附加_Pyor_PY前綴。 -
Include/internal/*.h應為 CPython 特別專屬的私有內部 C API。 此 API 不具備向下兼容保證並且不應在 CPython 以外被使用。 它們的公開僅適用於特別限定的需求例如調試器和性能分析等必須直接訪問 CPython 內部數據而不通過調用函數的應用。 此 API 現在是通過make install安裝的。
(由 Victor Stinner 在 bpo-35134 和 bpo-35081 中貢獻,相關工作由 Eric Snow 在 Python 3.7 中發起。)
-
-
某些宏已被轉換為靜態內聯函數:形參類型和返回類型定義良好,它們不再會有與宏相關的問題,變量具有局部作用域。 例如:
-
PyObject_INIT(),PyObject_INIT_VAR() -
私有函數:
_PyObject_GC_TRACK(),_PyObject_GC_UNTRACK(),_Py_Dealloc()
(由 Victor Stinner 在 bpo-35059 中貢獻。)
-
PyByteArray_Init()和PyByteArray_Fini()函數已被移除。 它們自 Python 2.7.4 和 Python 3.2.0 起就沒有任何用處,被排除在受限 API (穩定版 ABI) 之外,並且未被寫入文檔。 (由 Victor Stinner 在 bpo-35713 中貢獻。) -
PyExceptionClass_Name()的結果類型現在是const char *而非char *。 (由 Serhiy Storchaka 在 bpo-33818 中貢獻。) -
Modules/Setup.dist與Modules/Setup兩者的共存已被移除。 之前在更新 CPython 源碼樹時,開發者必須手動拷貝Modules/Setup.dist(在源碼樹內) 到Modules/Setup(在構建樹內) 以反映上游的任何改變。 舊特性對打包者來說有一點益處,但代價是對追蹤 CPython 開發進程的開發者造成經常性的麻煩,因為忘記拷貝該文件可能導致構建失敗。現在構建系統總是會從源碼樹內的
Modules/Setup讀取數據。 建議希望定制該文件的開發者在 CPython 的一個 git 分叉或補丁文件中維護他們的更改,就如他們對源碼樹做任何其他改變時一樣。(由 Antoine Pitrou 在 bpo-32430 中貢獻。)
-
將 Python 數字轉換為 C 整型的函數例如
PyLong_AsLong()以及帶有'i'之類整型轉換格式單元的參數解析函數例如PyArg_ParseTuple()現在如果可能將會使用__index__()特殊方法而不是__int__()。 對於帶有__int__()方法但沒有__index__()方法的對象 (例如Decimal和Fraction) 將會發出棄用警告。 對於實現了__index__()的對象PyNumber_Check()現在將返回1。PyNumber_Long(),PyNumber_Float()和PyFloat_AsDouble()現在如果可能也將會使用__index__()方法。 (由 Serhiy Storchaka 在 bpo-36048 和 bpo-20092 中貢獻。) -
堆分配類型對象現在將增加它們在
PyObject_Init()(及其對應的宏PyObject_INIT) 中的引用計數而不是在PyType_GenericAlloc()中。 修改實例分配或中止分配的類型可能需要進行調整。 (由 Elizondo 在 bpo-35810 中貢獻。) -
新增函數
PyCode_NewWithPosOnlyArgs()允許創建代碼對象例如PyCode_New(),但帶有一個額外的 posonlyargcount 形參以指明僅限位置參數的數量。 (由 Pablo Galindo 在 bpo-37221 中貢獻。) -
Py_SetPath()現在會將sys.executable設為程序完整路徑 (Py_GetProgramFullPath()) 而不是程序名稱 (Py_GetProgramName())。 (由 Victor Stinner 在 bpo-38234 中貢獻。)
棄用
-
distutils 的
bdist_wininst命令現在已棄用,請改用bdist_wheel(wheel 包)。 (由 Victor Stinner 在 bpo-37481 中貢獻。) -
ElementTree模塊中的已棄用方法getchildren()和getiterator()現在會引發DeprecationWarning而不是PendingDeprecationWarning。 它們將在 Python 3.9 中被移除。 (由 Serhiy Storchaka 在 bpo-29209 中貢獻。) -
Passing an object that is not an instance of
concurrent.futures.ThreadPoolExecutortoloop.set_default_executor()is deprecated and will be prohibited in Python 3.9. (Contributed by Elvis Pranskevichus in bpo-34075.) -
xml.dom.pulldom.DOMEventStream,wsgiref.util.FileWrapper和fileinput.FileInput的__getitem__()方法已被棄用。這些方法的實現會忽略它們的 index 形參,並改為返回下一條目。 (由 Berker Peksag 在 bpo-9372 中貢獻。)
-
typing.NamedTuple類已棄用了_field_types屬性而改用具有同樣信息的__annotations__屬性。 (由 Raymond Hettinger 在 bpo-36320 中貢獻。) -
ast類Num,Str,Bytes,NameConstant和Ellipsis被視為已棄用並將在未來的 Python 版本中被移除。 應當改用Constant。 (由 Serhiy Storchaka 在 bpo-32892 中貢獻。) -
ast.NodeVisitor的方法visit_Num(),visit_Str(),visit_Bytes(),visit_NameConstant()和visit_Ellipsis()現在已被棄用,並且在未來的 Python 版本中將不再被調用。 添加visit_Constant()方法來處理所有常量節點。 (由 Serhiy Storchaka 在 bpo-36917 中貢獻。) -
asyncio.coroutine()decorator 已棄用並將在 3.10 版中被移除。 原有的@asyncio.coroutine請改用async def來替代。 (由 Andrew Svetlov 在 bpo-36921 中貢獻。) -
In
asyncio, the explicit passing of a loop argument has been deprecated and will be removed in version 3.10 for the following:asyncio.sleep(),asyncio.gather(),asyncio.shield(),asyncio.wait_for(),asyncio.wait(),asyncio.as_completed(),asyncio.Task,asyncio.Lock,asyncio.Event,asyncio.Condition,asyncio.Semaphore,asyncio.BoundedSemaphore,asyncio.Queue,asyncio.create_subprocess_exec(), andasyncio.create_subprocess_shell(). -
The explicit passing of coroutine objects to
asyncio.wait()has been deprecated and will be removed in version 3.11. (Contributed by Yury Selivanov in bpo-34790.) -
gettext模塊中的下列函數和方法已被棄用:lgettext(),ldgettext(),lngettext()和ldngettext()。 它們返回已編碼的字節串,如果轉換后的字符串存在編碼問題你將可能遭遇預期之外的異常。 更好的做法是使用 Python 3 中返回 Unicode 字符串的操作作為替代。 前面的函數都早已不宜使用。函數
bind_textdomain_codeset(),方法output_charset()和set_output_charset(),以及函數translation()和install()的 codeset 形參也憶被棄用,因為它們僅適用於l*gettext()函數。 (由 Serhiy Storchaka 在 bpo-33710 中貢獻。) -
threading.Thread的isAlive()方法已棄用。 (由 Dong-hee Na 在 bpo-35283 中貢獻。) -
許多接受整數參數的內置和擴展模塊的函數現在將對傳入
Decimal,Fraction以及任何其他可被轉換為整數但會丟失精度(即具有__int__()方法但沒有__index__()方法)的對象發出棄用警告。 在未來的版本中則將報錯。 (由 Serhiy Storchaka 在 bpo-36048 中貢獻。) -
以下參數作為關鍵字參數傳遞的方式已被棄用:
-
functools.partialmethod(),weakref.finalize(),profile.Profile.runcall(),cProfile.Profile.runcall(),bdb.Bdb.runcall(),trace.Trace.runfunc()與curses.wrapper()中的 func。 -
unittest.TestCase.addCleanup()中的 function。 -
concurrent.futures.ThreadPoolExecutor和concurrent.futures.ProcessPoolExecutor的submit()方法中的 fn。 -
contextlib.ExitStack.callback(),contextlib.AsyncExitStack.callback()和contextlib.AsyncExitStack.push_async_callback()中的 callback。 -
multiprocessing.managers.Server和multiprocessing.managers.SharedMemoryServer的create()方法中的 c 和 typeid。 -
weakref.finalize()中的 obj。
在未來版本的 Python 中,它們將成為 僅限位置參數。 (由 Serhiy Storchaka 在 bpo-36492 中貢獻。)
-
API 與特性的移除
下列特性與 API 已從 Python 3.8 中移除:
-
自 Python 3.3 起,從
collections導入 ABC 的做法已棄用,而應當從collections.abc執行導入。 從 collections 導入的操作在 3.8 中已標記為被移除,但將推遲到 3.9 中實施。 (參見 bpo-36952。) -
macpath模塊,在 Python 3.7 中棄用,現已被移除。 (由 Victor Stinner 在 bpo-35471 中貢獻。) -
函數
platform.popen()已被移除,它自 Python 3.3 起就已被棄用:請改用os.popen()。 (由 Victor Stinner 在 bpo-35345 中貢獻。) -
函數
time.clock()已被移除,它自 Python 3.3 起就已被棄用:請根據具體需求改用time.perf_counter()或time.process_time()以獲得具有良好定義的行為。 (由 Matthias Bussonnier 在 bpo-36895 中貢獻。) -
pyvenv腳本已被移除,推薦改用python3.8 -m venv來幫助消除容易混淆pyvenv腳本所關聯的 Python 解釋器這一問題。 (由 Brett Cannon 在 bpo-25427 中貢獻。) -
parse_qs,parse_qsl和escape已從cgi模塊中被移除。 這些函數自 Python 3.2 或更早就已被棄用。 它們應改為從urllib.parse和html模塊導入。 -
filemode函數已從tarfile模塊中被移除。 該函數未被寫入文檔,自 Python 3.3 起就已棄用。 -
XMLParser構造器不再接受 html 參數。 它從來沒有任何作用並在 Python 3.4 中已被棄用。 所有其他形參現在都是 僅限關鍵字參數。 (由 Serhiy Storchaka 在 bpo-29209 中貢獻。) -
XMLParser的doctype()方法已被移除。 (由 Serhiy Storchaka 在 bpo-29209 中貢獻。) -
"unicode_internal" 編解碼器已被移除。 (由 Inada Naoki 在 bpo-36297 中貢獻。)
-
sqlite3模塊的Cache和Statement對象已不再公開給用戶。 (由 Aviv Palivoda 在 bpo-30262 中貢獻。) -
fileinput.input()和fileinput.FileInput()中自 Python 3.6 起就已被忽略並棄用的bufsize關鍵字參數已被移除。 由 Matthias Bussonnier 在 bpo-36952 中貢獻。) -
在 Python 3.7 中棄用的函數
sys.set_coroutine_wrapper()和sys.get_coroutine_wrapper()已被移除。 (由 Matthias Bussonnier 在 bpo-36933 中貢獻。)
移植到 Python 3.8
本節列出了先前描述的更改以及可能需要更改代碼的其他錯誤修正.
Python 行為的改變
-
yield 表達式(包括
yield和yield from子句)現在不允許在推導式和生成器表達式中使用(但for子句最左邊的可迭代對象表達式除外)。 (由 Serhiy Storchaka 在 bpo-10544 中貢獻。) -
當標識號檢測 (
is和is not) 與特定類型的字面值 (例如字符串和數字) 一同使用時編譯器現在會產生SyntaxWarning。 這在 CPython 中通常是可行的,但並不被語言定義所保證。 該警告會建議用戶改用相等性檢測 (==and!=)。 (由 Serhiy Storchaka 在 bpo-34850 中貢獻。) -
CPython 解釋器在某些情況下可以忽略異常。 在 Python 3.8 中這種情況會更少發生。 特別地,從類型字典獲取屬性時引發的異常不會再被忽略。 (由 Serhiy Storchaka 在 bpo-35459 中貢獻。)
-
從內置類型
bool,int,float,complex和標准庫的一些類中移除了__str__實現。 它們現在會從object繼承__str__()。 作為結果,在這些類的子類中定義__repr__()方法將會影響它們的字符串表示。 (由 Serhiy Storchaka 在 bpo-36793 中貢獻。) -
在 AIX 上,
sys.platform將不再包含主要版本號。 它將總是'aix'而不再是'aix3'..'aix7'。 由於較舊的 Python 版本會包含該版本號,因此推薦總是使用sys.platform.startswith('aix')。 (由 M. Felt 在 bpo-36588 中貢獻。) -
現在
PyEval_AcquireLock()和PyEval_AcquireThread()如果當解釋器終結化時被調用將會終結當前線程,以使它們與PyEval_RestoreThread(),Py_END_ALLOW_THREADS()以及PyGILState_Ensure()保持一致。 如果不想要這樣的行為,請通過檢測_Py_IsFinalizing()或sys.is_finalizing()來保護該調用。 (由 Joannah Nanjekye 在 bpo-36475 中貢獻。)
更改的Python API
-
在 Windows 上
os.getcwdb()函數現在會使用 UTF-8 編碼格式而不是 ANSI 代碼頁:請參看 PEP 529 了解具體原因。 該函數在 Windows 上不再被棄用。 (由 Victor Stinner 在 bpo-37412 中貢獻。) -
現在
subprocess.Popen在某些情況下會使用os.posix_spawn()以獲得更好的性能。 在適用於 Linux 的 Windows 子系統和 QEMU 用戶模擬器上,使用os.posix_spawn()的Popen構造器不會再因為“找不到程序”這樣的錯誤引發異常。 而是讓子進程失敗並返回一個非零的returncode。 (由 Joannah Nanjekye 和 Victor Stinner 在 bpo-35537 中貢獻。) -
The preexec_fn argument of *
subprocess.Popenis no longer compatible with subinterpreters. The use of the parameter in a subinterpreter now raisesRuntimeError. (Contributed by Eric Snow in bpo-34651, modified by Christian Heimes in bpo-37951.) -
imap.IMAP4.logout()方法不會再靜默地忽略任意異常。 (由 Victor Stinner 在 bpo-36348 中貢獻。) -
函數
platform.popen()已被移除,它自 Python 3.3 起就已被棄用:請改用os.popen()。 (由 Victor Stinner 在 bpo-35345 中貢獻。) -
當傳入多模數據時
statistics.mode()函數不會再引發異常。 它將改為返回在輸入數據中遇到的第一個模式。 (由 Raymond Hettinger 在 bpo-35892 中貢獻。) -
tkinter.ttk.Treeview類的selection()方法不再接受參數。 帶參數調用該方法來改變選擇在 Python 3.6 中已棄用。 請使用專門方法例如selection_set()來改變選擇。 (由 Serhiy Storchaka 在 bpo-31508 中貢獻。) -
xml.dom.minidom的writexml(),toxml()和toprettyxml()方法以及xml.etree的write()方法現在會保留用戶指定的屬性順序。 (由 Diego Rojas 和 Raymond Hettinger 在 bpo-34160 中貢獻。) -
附帶
'r'旗標打開的dbm.dumb數據庫現在將是只讀的。 如果數據庫不存在,附帶'r'和'w'旗標的dbm.dumb.open()不會再創建數據庫。 (由 Serhiy Storchaka 在 bpo-32749 中貢獻。) -
在
XMLParser的子類中定義的doctype()方法將不會再被調用,並將導致發出RuntimeWarning而不是DeprecationWarning。 請在目標上定義doctype()方法來處理 XML doctype 聲明。 (由 Serhiy Storchaka 在 bpo-29209 中貢獻。) -
現在當自定義元類未在傳給
type.__new__的命名空間中提供__classcell__入口時將引發RuntimeError。 在 Python 3.6--3.7 中是則是引發DeprecationWarning。 (由 Serhiy Storchaka 在 bpo-23722 中貢獻。) -
cProfile.Profile類現在可被用作上下文管理器。 (由 Scott Sanderson 在 bpo-29235 中貢獻。) -
shutil.copyfile(),shutil.copy(),shutil.copy2(),shutil.copytree()和shutil.move()會使用平台專屬的 "fast-copy" 系統調用(參見 依賴於具體平台的高效拷貝操作 一節)。 -
shutil.copyfile()在 Windows 上的默認緩沖區大小從 16 KiB 改為 1 MiB。 -
PyGC_Head結構已被完全改變。 所有接觸到該結構的代碼都應當被重寫。 (參見 bpo-33597。) -
PyInterpreterState結構已被移入 "internal" 頭文件(特別是 Include/internal/pycore_pystate.h)。 不透明的PyInterpreterState作為僅有 API(以及穩定版 ABI)的一部分仍然可用。 文檔指明該結構的任何字段都不是公有的,因此我們希望沒人在使用它們。 但是,如果你確實依賴其中某一個或更多個私有字段並且沒有其他替代選項,則請開一個 BPO 問題。 我們將盡力幫助你進行調整(可能包括向公有 API 添加訪問器函數)。 (參見 bpo-35886。) -
現在所有平台下的
mmap.flush()方法都會在成功時返回None並在錯誤時引發異常。 之前它的行為取決於具體平台: Windows 下會在成功時返回非零值;在失敗時返回零。 Unix 下會在成功時返回零;在失敗時引發錯誤。 (由 Berker Peksag 在 bpo-2122 中貢獻。) -
xml.dom.minidom和xml.sax模塊默認將不再處理外部實體。 (由 Christian Heimes 在 bpo-17239 中貢獻。) -
從只讀的
dbm數據庫 (dbm.dumb,dbm.gnu或dbm.ndbm) 刪除鍵將會引發error(dbm.dumb.error,dbm.gnu.error或dbm.ndbm.error) 而不是KeyError。 (由 Xiang Zhang 在 bpo-33106 中貢獻。) -
Simplified AST for literals. All constants will be represented as
ast.Constantinstances. Instantiating old classesNum,Str,Bytes,NameConstantandEllipsiswill return an instance ofConstant. (Contributed by Serhiy Storchaka in bpo-32892.) -
expanduser()在 Windows 上現在改用USERPROFILE環境變量而不再使用HOME,后者通常不會為一般用戶賬戶設置。 (由 Anthony Sottile 在 bpo-36264 中貢獻。) -
The exception
asyncio.CancelledErrornow inherits fromBaseExceptionrather thanException. (Contributed by Yury Selivanov in bpo-32528.) -
The function
asyncio.wait_for()now correctly waits for cancellation when using an instance ofasyncio.Task. Previously, upon reaching timeout, it was cancelled and immediately returned. (Contributed by Elvis Pranskevichus in bpo-32751.) -
The function
asyncio.BaseTransport.get_extra_info()now returns a safe to use socket object when 'socket' is passed to the name parameter. (Contributed by Yury Selivanov in bpo-37027.) -
asyncio.BufferedProtocolhas graduated to the stable API.
-
DLL dependencies for extension modules and DLLs loaded with
ctypeson Windows are now resolved more securely. Only the system paths, the directory containing the DLL or PYD file, and directories added withadd_dll_directory()are searched for load-time dependencies. Specifically,PATHand the current working directory are no longer used, and modifications to these will no longer have any effect on normal DLL resolution. If your application relies on these mechanisms, you should check foradd_dll_directory()and if it exists, use it to add your DLLs directory while loading your library. Note that Windows 7 users will need to ensure that Windows Update KB2533623 has been installed (this is also verified by the installer). (Contributed by Steve Dower in bpo-36085.) -
關聯到 pgen 的頭文件和函數在其被純 Python 實現取代后已被移除。 (由 Pablo Galindo 在 bpo-36623 中貢獻。)
-
types.CodeType在構造器的第二個位置新增了一個形參 (posonlyargcount) 以支持在 PEP 570 中定義的僅限位置參數。 第一個參數 (argcount) 現在表示位置參數的總數量 (包括僅限位置參數)。types.CodeType中新增的replace()方法可用於讓代碼支持 future 特性。
C API 中的改變
-
PyCompilerFlags結構體添加了一個新的 cf_feature_version 字段。 它應當被初始化為PY_MINOR_VERSION。 該字段默認會被忽略,當且僅當PyCF_ONLY_AST在 cf_flags 中設置旗標時才會被使用。 (由 Guido van Rossum 在 bpo-35766 中貢獻。) -
PyEval_ReInitThreads()函數已從 C API 中移除。 它不應當被顯式地調用;請改用PyOS_AfterFork_Child()。 (由 Victor Stinner 在 bpo-36728 中貢獻。) -
在 Unix 上,C 擴展不會再被鏈接到 libpython,但 Android 和 Cygwin 例外。 當 Python 被嵌入時,
libpython不可使用RTLD_LOCAL加載,而要改用RTLD_GLOBAL。 之前使用RTLD_LOCAL已經不可能加載未鏈接到libpython的 C 擴展了,例如通過Modules/Setup的*shared*部分構建的標准庫 C 擴展。 (由 Victor Stinner 在 bpo-21536 中貢獻。) -
在解析或構建值時(例如
PyArg_ParseTuple(),Py_BuildValue(),PyObject_CallFunction()等等)使用形如#的格式而不定義PY_SSIZE_T_CLEAN現在將會引發DeprecationWarning。 它將在 3.10 或 4.0 中被移除。 請參閱 語句解釋及變量編譯 了解詳情。 (由 Inada Naoki 在 bpo-36381 中貢獻。) -
堆分配類型的實例(例如使用
PyType_FromSpec()創建的實例)會保存一個對其類型對象的引用。 提升這些類型對象引用計數的操作已從PyType_GenericAlloc()移至更低層級的函數PyObject_Init()和PyObject_INIT()。 這使用通過This makes types created throughPyType_FromSpec()所創建類型的行為與管理代碼中的其他類保持一致。靜態分配類型將不受影響。
在大部分情況下,這應該都不會有附帶影響。 但是,在分配實例后手動提升引用計數的類型(也許是為了繞過漏洞)現在可能永遠不會被銷毀。 要避免這種情況,這些類需要在實例撤銷分配期間在類型對象上調用 Py_DECREF。
要正確地將這些類型移植到 3.8,請應用以下修改:
-
在分配實例之后在類型對象上移除
Py_INCREF—— 如果有的話。 這可以發生在調用PyObject_New(),PyObject_NewVar(),PyObject_GC_New(),PyObject_GC_NewVar()或任何其他使用PyObject_Init()或PyObject_INIT()的自定義分配器之后。示例:
static foo_struct * foo_new(PyObject *type) { foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type); if (foo == NULL) return NULL; #if PY_VERSION_HEX < 0x03080000 // Workaround for Python issue 35810; no longer necessary in Python 3.8 PY_INCREF(type) #endif return foo; } -
確保所有堆分配類型的自定義
tp_dealloc函數會減少類型的引用計數。示例:
static void foo_dealloc(foo_struct *instance) { PyObject *type = Py_TYPE(instance); PyObject_GC_Del(instance); #if PY_VERSION_HEX >= 0x03080000 // This was not needed before Python 3.8 (Python issue 35810) Py_DECREF(type); #endif }
(由 Eddie Elizondo 在 bpo-35810 中貢獻。)
-
-
Py_DEPRECATED()宏已經針對 MSVC 實現。 這個宏現在必須放在符號名稱之前。示例:
Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);(由 Zackery Spytz 在 bpo-33407 中貢獻。)
-
解釋器將不再假裝支持跨發布版本的擴展類型二進制兼容性。 由第三方擴展模塊所導出的
PyTypeObject應該具有當前 Python 版本所要求的所有空位,包括tp_finalize(Py_TPFLAGS_HAVE_FINALIZE不會再在讀取tp_finalize之前被檢查)。(由 Antoine Pitrou 在 bpo-32388 中貢獻。)
-
PyCode_New()在第二個位置添加了新的形參 (posonlyargcount) 以支持 PEP 570,指明僅限位置參數的數量。 -
函數
PyNode_AddChild()和PyParser_AddToken()現在接受兩個額外的int參數 end_lineno 和 end_col_offset。 -
允許 MinGW 工具直接鏈接到
python38.dll的libpython38.a文件已不再包含於標准的 Windows 分發包中。 如果你需要此文件,可使用gendef和dlltool工具來生成它,這些工具是 MinGW binutils 包的一部分:gendef - python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a
已安裝的
pythonXY.dll所在位置將取決於安裝選項以及 Windows 的版本和語言。 請參閱 在Windows上使用 Python 了解更多信息。 該結果庫應當放在與pythonXY.lib相同的目錄下,這通常是你的 Python 安裝路徑下的libs目錄。(由 Steve Dower 在 bpo-37351 中貢獻。)
CPython 字節碼的改變
-
解釋器循環已通過將塊堆棧展開邏輯移入編譯器獲得了簡化。 編譯器現在會發出顯式指令來調整值堆棧並為
break,continue和return調用清除代碼。移除了操作碼
BREAK_LOOP,CONTINUE_LOOP,SETUP_LOOP和SETUP_EXCEPT。 添加了新的操作碼ROT_FOUR,BEGIN_FINALLY,CALL_FINALLY和POP_FINALLY。 修改了END_FINALLY和WITH_CLEANUP_START的行為。(由 Mark Shannon, Antoine Pitrou 和 Serhiy Storchaka 在 bpo-17611 中貢獻。)
-
添加了新的操作碼
END_ASYNC_FOR用於處理當等待async for循環的下一項時引發的異常。 (由 Serhiy Storchaka 在 bpo-33041 中貢獻。) -
MAP_ADD現在會預期值為棧的第一個元素而鍵為第二個元素。 作出此改變以使得字典推導式能如 PEP 572 所提議的那樣,鍵總是會在值之前被求值。 (由 Jörn Heissler 在 bpo-35224 中貢獻。)
演示和工具
添加了一個檢測腳本用於對訪問變量的不同方式進行計時: Tools/scripts/var_access_benchmark.py。 (由 Raymond Hettinger 在 bpo-35884 中貢獻。)
Here's a summary of performance improvements since Python 3.3:
Python version 3.3 3.4 3.5 3.6 3.7 3.8
-------------- --- --- --- --- --- ---
Variable and attribute read access:
read_local 4.0 7.1 7.1 5.4 5.1 3.9
read_nonlocal 5.3 7.1 8.1 5.8 5.4 4.4
read_global 13.3 15.5 19.0 14.3 13.6 7.6
read_builtin 20.0 21.1 21.6 18.5 19.0 7.5
read_classvar_from_class 20.5 25.6 26.5 20.7 19.5 18.4
read_classvar_from_instance 18.5 22.8 23.5 18.8 17.1 16.4
read_instancevar 26.8 32.4 33.1 28.0 26.3 25.4
read_instancevar_slots 23.7 27.8 31.3 20.8 20.8 20.2
read_namedtuple 68.5 73.8 57.5 45.0 46.8 18.4
read_boundmethod 29.8 37.6 37.9 29.6 26.9 27.7
Variable and attribute write access:
write_local 4.6 8.7 9.3 5.5 5.3 4.3
write_nonlocal 7.3 10.5 11.1 5.6 5.5 4.7
write_global 15.9 19.7 21.2 18.0 18.0 15.8
write_classvar 81.9 92.9 96.0 104.6 102.1 39.2
write_instancevar 36.4 44.6 45.8 40.0 38.9 35.5
write_instancevar_slots 28.7 35.6 36.1 27.3 26.6 25.7
Data structure read access:
read_list 19.2 24.2 24.5 20.8 20.8 19.0
read_deque 19.9 24.7 25.5 20.2 20.6 19.8
read_dict 19.7 24.3 25.7 22.3 23.0 21.0
read_strdict 17.9 22.6 24.3 19.5 21.2 18.9
Data structure write access:
write_list 21.2 27.1 28.5 22.5 21.6 20.0
write_deque 23.8 28.7 30.1 22.7 21.8 23.5
write_dict 25.9 31.4 33.3 29.3 29.2 24.7
write_strdict 22.9 28.4 29.9 27.5 25.2 23.1
Stack (or queue) operations:
list_append_pop 144.2 93.4 112.7 75.4 74.2 50.8
deque_append_pop 30.4 43.5 57.0 49.4 49.2 42.5
deque_append_popleft 30.8 43.7 57.3 49.7 49.7 42.8
Timing loop:
loop_overhead 0.3 0.5 0.6 0.4 0.3 0.3
(Measured from the macOS 64-bit builds found at python.org)
Python 3.8.1 中的重要變化
出於重要的安全性考量,asyncio.loop.create_datagram_endpoint() 的 reuse_address 形參不再被支持。 這是由 UDP 中的套接字選項 SO_REUSEADDR 的行為導致的。 更多細節請參閱 loop.create_datagram_endpoint() 的文檔。 (由 Kyle Stanley, Antoine Pitrou 和 Yury Selivanov 在 bpo-37228 中貢獻。。)
Notable changes in Python 3.8.2
Fixed a regression with the ignore callback of shutil.copytree(). The argument types are now str and List[str] again. (Contributed by Manuel Barkhau and Giampaolo Rodola in bpo-39390.)
