Python 3.9 有什么新�化¶

编者:

�ukasz Langa

这篇文章介�了 Python 3.9 相比 3.8 增加的新特性。 Python 3.9 �布于 2020年 10 月 5 日。 更详细的信���阅 更新日志。

��

PEP 596 - Python 3.9 �布计划

摘� -- �布�点¶

新的语法特性:

  • PEP 584,为 dict 增加å�ˆå¹¶è¿�算符;

  • PEP 585,标准多项集中的类型标注泛型。

  • PEP 614,放宽对装饰器的语法é™�制。

新的内置特性:

  • PEP 616,移除å‰�缀和å�Žç¼€çš„字符串方法。

标准库中的新特性:

  • PEP 593,ç�µæ´»å‡½æ•°å’Œå�˜é‡�注解;

  • 添加了 os.pidfd_open() 以å…�许ä¸�带竞争和信å�·çš„进程管ç�†ã€‚

解释器的改进:

  • PEP 573,从 C 扩展类型的方法快速访问模å�—状æ€�ï¼›

  • PEP 617,CPython 现在使用基于 PEG 的新解æž�器;

  • 一些 Python 内置类型(rangeã€�tupleã€�setã€�frozensetã€�listã€�dict)现已使用 PEP 590 vectorcall 加速;

  • 垃圾回收ä¸�会因æ�¢å¤�的对象而阻塞;

  • 一些 Python 模å�—(_abcã€�audioopã€�_bz2ã€�_codecsã€�_contextvarsã€�_cryptã€�_functoolsã€�_jsonã€�_localeã€�mathã€�operatorã€�resourceã€�timeã€�_weakref)现已使用 PEP 489 中定义的多段åˆ�始化;

  • 一些标准库模å�— (audioopã€�astã€�grpã€�_hashlibã€�pwdã€�_posixsubprocessã€�randomã€�selectã€�structã€�termiosã€�zlib) 现已使用 PEP 384 中定义的稳定 ABI。

新的库模�:

  • PEP 615,标准库的 zoneinfo 模å�—现已支æŒ� IANA 时区数æ�®åº“ï¼›

  • 图的拓扑排åº�实现现在已由新的 graphlib 模å�—æ��供。

�布进程的�化:

  • PEP 602,CPython 采用年度å�‘布周期。

请检查代�中的 DeprecationWarning。¶

Python 2.7 支�未终止时,为了实现�下兼容 Python 2.7,Python 3 �留了许多旧版功能。Python 2 的支�终止�,已�移除了一部分�下兼容层,剩余部分很快也会被移除。这几年,大部分兼容层都会触� DeprecationWarning 警告。例如,2012 年�布 Python 3.3 �,用 collections.Mapping 替代 collections.abc.Mapping 就会触� DeprecationWarning。

请用 -W default 命令行选项测试应用程��查看 DeprecationWarning 和 PendingDeprecationWarning,甚至�以用 -W error 将它们视为错误。 �以用 警告过滤器 忽略�自第三方代�的警告。

Python 3.9 是最�一个�供 Python 2 �下兼容层的版本,以给予 Python 项目维护者更多时间移除 Python 2 支�,添加 Python 3.9 支�。

collections 模�中 抽象基类 的别�,例如 collections.abc.Mapping 的别� collections.Mapping 会为�下兼容最��留一个�行版。 这些内容将在 Python 3.10 中移除。

更通俗的说法是,请在 Python 开�模� 下�行测试,这样�有助于让代�兼容 Python 的�续版本。

注:一些�期已弃用的内容也将在此 Python 版本中移除。 详� 移除 一节。

新的特性¶

字典�并与更新�算符¶

�并 (|) 与更新 (|=) �算符已被加入内置的 dict 类。 它们为现有的 dict.update 和 {**d1, **d2} 字典�并方法�供了补充。

示例:

>>> x = {"key1": "value1 from x", "key2": "value2 from x"}
>>> y = {"key2": "value2 from y", "key3": "value3 from y"}
>>> x | y
{'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}
>>> y | x
{'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}

详� PEP 584。(Brandt Bucher 在 bpo-36144 中的贡献。)

新增用于移除�缀和�缀的字符串方法¶

增加了 str.removeprefix(prefix) 和 str.removesuffix(suffix) 用于方便地从字符串移除�需�的�缀或�缀。 也增加了 bytes, bytearray 以� collections.UserString 的对应方法。 请�阅 PEP 616 了解详情。 (由 Dennis Sweeney 在 bpo-39939 中贡献。)

标准多项集中的类型标注泛型¶

在类型标注中现在你�以使用内置多项集类型例如 list 和 dict 作为通用类型而�必从 typing 导入对应的大写形�类型� (例如 List 和 Dict)。 标准库中的其他一些类型现在�样也是通用的,例如 queue.Queue。

示例:

def greet_all(names: list[str]) -> None:
    for name in names:
        print("Hello", name)

详� PEP 585。(由 Guido van Rossum�Ethan Smith 和 Batuhan Taşkaya 在 bpo-39481 中贡献。)

新的解�器¶

Python 3.9 使用于基于 PEG 的新解�器替代 LL(1)。 新解�器的性能与旧解�器大致相当,但 PEG 在设计新语言特性时的形�化比 LL(1) 更�活。 我们将在 Python 3.10 �之�版本中开始使用这��活性。

ast 模�会使用新解�器并会生�与旧解�器一致的 AST。

在 Python 3.10 中,旧解�器将被移除,�赖于它的所有功能也将被移除(主�是 parser 模�,它早已被弃用)。 �有 在 Python 3.9 中,你�以使用命令行开关 (-X oldparser) 或环境�� (PYTHONOLDPARSER=1) 切�回 LL(1) 解�器。

请�阅 PEP 617 了解详情。 (由 Guido van Rossum, Pablo Galindo 和 Lysandros Nikolaou 在 bpo-40334 中贡献。)

其他语言特性修改¶

  • __import__() 现在会引å�‘ ImportError 而ä¸�是 ValueError,å�Žè€…曾ç»�会在相对导入超出其最高层级包时å�‘生。 (由 Ngalim Siregar 在 bpo-37444 中贡献。)

  • Python 现在会获å�–命令行中指定的脚本文件å�� (例如: python3 script.py) çš„ç»�对路径: __main__ 模å�—çš„ __file__ 属性将是一个ç»�对路径,而ä¸�是相对路径。 现在此路径在当å‰�目录通过 os.chdir() 被改å�˜å�Žä»�å°†ä¿�æŒ�有效。 作为附带效果,回溯信æ�¯ä¹Ÿå°†åœ¨æ­¤æƒ…况下为 __main__ 模å�—帧显示ç»�对路径。 (由 Victor Stinner 在 bpo-20443 中贡献。)

  • 在 Python å¼€å�‘模å¼� 以å�Š è°ƒè¯•ç¼–è¯‘ç‰ˆæœ¬ 中,现在会针对字符串编ç �和解ç �æ“�作检查 encoding å’Œ errors å�‚数。 例如: open(), str.encode() å’Œ bytes.decode()。

    默认设置下,为��性能,errors �数�会在第一次�生编�/解�错误时被检查,并且对于空字符串 encoding �数有时会被忽略。 (由 Victor Stinner 在 bpo-37388 中贡献。)

  • "".replace("", s, n) 对于所有é�žé›¶çš„ n 都将返回 s 而ä¸�是空字符串。 现在此方法会与 "".replace("", s) ä¿�æŒ�一致。 对于 bytes å’Œ bytearray 对象也有类似的修改。 (由 Serhiy Storchaka 在 bpo-28029 中贡献。)

  • 任何有效的表达å¼�现在都å�¯è¢«ç”¨ä½œ decorator。 在之å‰�版本中,相关语法则更为严格。 请å�‚阅 PEP 614 了解详情。 (由 Brandt Bucher 在 bpo-39702 中贡献。)

  • 改进了 typing 模å�—的帮助信æ�¯ã€‚ 现在将为所有特殊形å¼�和特殊通用别å�� (例如 Union å’Œ List) 显示文档字符串。 使用 help() 时传入通用别å��例如 List[int] 将显示对应实体类型 (这里对应的是 list) 的帮助信æ�¯ã€‚ (由 Serhiy Storchaka 在 bpo-40257 中贡献。)

  • aclose() / asend() / athrow() 的并行è¿�行现在已被ç¦�止,且 ag_running 现在会å��映异步生æˆ�器的实际è¿�行状æ€�。 (由 Yury Selivanov 在 bpo-30773 中贡献。)

  • 调用 __iter__ 方法时å�‘生的é�žé¢„期错误ä¸�会å†�被 in è¿�算符以å�Š operator çš„ contains(), indexOf() å’Œ countOf() 中的 TypeError 所掩盖。 (由 Serhiy Storchaka 在 bpo-40824 中贡献。)

  • 未加圆括å�·çš„ lambda 表达å¼�ä¸�能å†�作为推导å¼�和生æˆ�器表达å¼�çš„ if å­�å�¥çš„表达å¼�部分。 请å�‚阅 bpo-41848 å’Œ bpo-43755 了解详情。

新增模�¶

zoneinfo¶

zoneinfo 模�为标准库引入了 IANA 时区数�库。 它添加了 zoneinfo.ZoneInfo,这是一个基于系统时区数�的实体 datetime.tzinfo 实现。

示例:

>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta

>>> # Daylight saving time
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00
>>> dt.tzname()
'PDT'

>>> # Standard time
>>> dt += timedelta(days=7)
>>> print(dt)
2020-11-07 12:00:00-08:00
>>> print(dt.tzname())
PST

作为�包� IANA 数�库的平�的一个回退数��,还以第一方软件包的形��布了 tzdata 模� -- 通过 PyPI �行并由 CPython 核心团队维护。

��

PEP 615 -- 在标准库中支� IANA 时区数�库

PEP 由 Paul Ganssle 撰写并实现

graphlib¶

添加了新的 graphlib 模�,其中包� graphlib.TopologicalSorter 类��供图的拓扑排�功能。 (由 Pablo Galindo, Tim Peters 和 Larry Hastings 在 bpo-17005 中贡献。)

改进的模�¶

ast¶

将 indent 选项添加到 dump(),这�许它产生多行缩进的输出。 (由 Serhiy Storchaka 在 bpo-37995 中贡献。)

添加了 ast.unparse() 作为 ast 模�中的一个函数,它�被用��解� ast.AST 对象并产生相应的代�字符串,当它被解�时将会产生一个等价的 ast.AST 对象。 (由 Pablo Galindo 和 Batuhan Taskaya 在 bpo-38870 中贡献。)

为 AST 节点添加了文档字符串,其中包� ASDL 签�,�被用�构造对应的节点。 (由 Batuhan Taskaya 在 bpo-39638 中贡献。)

asyncio¶

出于��的安全性考�,asyncio.loop.create_datagram_endpoint() 的 reuse_address 形���被支�。 这是由 UDP 中的套接字选项 SO_REUSEADDR 的行为导致的。 更多细节请�阅 loop.create_datagram_endpoint() 的文档。 (由 Kyle Stanley, Antoine Pitrou 和 Yury Selivanov 在 bpo-37228 中贡献。。)

添加了新的 coroutine shutdown_default_executor(),它�为等待 ThreadPoolExecutor 结�关闭的默认执行器安排关闭日程�作。 此外,asyncio.run() 已被更新以使用新的 coroutine。 (由 Kyle Stanley 在 bpo-34037 中贡献。)

添加了 asyncio.PidfdChildWatcher,这是一个 Linux 专属的�监视器实现,它负责轮询进程的文件�述符。 (bpo-38692)

添加了新的 coroutine asyncio.to_thread()。 它主�被用于在�独线程中�行 IO 密集型函数以��阻塞事件循环,实质上就相当于是 run_in_executor() 的高层级版本,�直接接�关键字�数。 (由 Kyle Stanley 和 Yury Selivanov 在 bpo-32309 中贡献。)

当由于超时而�消任务时,asyncio.wait_for() 现在将会等待直到也在 timeout 值 <= 0 的情况下完��消。 就� timeout 值为正数时一样。 (由 Elvis Pranskevichus 在 bpo-32751 中贡献。)

当附带 ssl.SSLSocket 套接字调用�兼容的方法时 asyncio 现在会引� TyperError。 (由 Ido Michael 在 bpo-37404 中贡献。)

compileall¶

为��的 .pyc 文件添加了使用硬软件的�能性: hardlink_dupes 形�以� --hardlink-dupes 命令行选项。 (由 Lumír 'Frenzy' Balhar 在 bpo-40495 中贡献。)

新增了一些用于在结果 .pyc 文件中�纵路径的选项: stripdir, prependdir, limit_sl_dest 形�以� -s, -p, -e 命令行选项。 并使得为优化等级多次指定选项�为�能。 (由 Lumír 'Frenzy' Balhar 在 bpo-38112 中贡献。)

concurrent.futures¶

将新的 cancel_futures 形�添加到 concurrent.futures.Executor.shutdown(),�以�消尚未开始�行的所有挂起的 Future,而�必等待它们完��行�关闭执行器。 (由 Kyle Stanley 在 bpo-39349 中贡献。)

从 ThreadPoolExecutor 和 ProcessPoolExecutor 中移除了守护线程。 这改善与与�解释器的兼容性�它们在关闭进程时的�预测性。 (由 Kyle Stanley 在 bpo-39812 中贡献。)

现在 ProcessPoolExecutor 中的工作进程仅会在没有��用的空闲工作进程时按需产生。 这优化了�动开销并�少了由空闲工作进程导致的 CPU 时间�失。 (由 Kyle Stanley 在 bpo-39207 中贡献。)

curses¶

增加了 curses.get_escdelay(), curses.set_escdelay(), curses.get_tabsize() 以� curses.set_tabsize() 函数。(由 Anthony Sottile 在 bpo-38312 中贡献。)

datetime¶

datetime.date 的 isocalendar() 以� datetime.datetime 的 isocalendar() 等方法现在将返回 namedtuple() 而�是 tuple。 (由 Donghee Na 在 bpo-24416 中贡献。)

distutils¶

upload 命令现在会创建 SHA2-256 和 Blake2b-256 哈希摘�。 它会在�用 MD5 摘�的平�上跳过 MD5。 (由 Christian Heimes 在 bpo-40698 中贡献。)

fcntl¶

增加了 F_OFD_GETLK, F_OFD_SETLK 和 F_OFD_SETLKW 等常�。 (由 Donghee Na 在 bpo-38602 中贡献。)

ftplib¶

现在 FTP 和 FTP_TLS 当它们的构造器所给定的超时�数为零以防止创建�阻塞套接字时会引� ValueError。 (由 Donghee Na 在 bpo-39259 中贡献。)

gc¶

当垃圾回收器进行�些�活对象的收集时(在终结器被执行之�这些对象�以在隔离周期之外被访问),�会阻止对所有�然无法访问的对象的收集。 (由 Pablo Galindo 和 Tim Peters 在 bpo-38379 中贡献。)

增加了一个新的函数 gc.is_finalized() 用�检测一个对象是�已被垃圾回收器所终结。 (由 Pablo Galindo 在 bpo-39322 中贡献。)

hashlib¶

hashlib 模�现在会在�能的情况下使用 OpenSSL 中的 SHA3 哈希和 SHAKE XOF。 (由 Christian Heimes 在 bpo-37630 中贡献。)

内置的哈希模�现在�通过 ./configure --without-builtin-hashlib-hashes �用或通过 ./configure --with-builtin-hashlib-hashes=sha3,blake2 这样的形�有选择地�用以强制使用基于 OpenSSL 的实现。 (由 Christian Heimes 在 bpo-40479 中贡献)

http¶

添加 HTTP 状�� 103 EARLY_HINTS, 418 IM_A_TEAPOT 和 425 TOO_EARLY 到 http.HTTPStatus。 (由 Donghee Na 在 bpo-39509 以� Ross Rhodes 在 bpo-39507 中贡献。)

IDLE 与 idlelib¶

添加了切�光标闪��止的选项。 (由 Zackery Spytz 在 bpo-4603 中贡献。)

Esc 键现在会关闭 IDLE 补全�示窗�。 (由 Johnny Najera 在 bpo-38944 中贡献。)

添加关键字到模��称补全列表。 (由 Terry J. Reedy 在 bpo-37765 中贡献。)

3.9 维护版本中的新内容

使 IDLE 调用 sys.excepthook() (当�动时没有 '-n' )。用户钩�以�是被忽略的。 (由 Ken Hilton 在 bpo-43008 中贡献。)

上述修改已被��移�到 3.8 维护�行版中。

�新安排设置对�框。 将常规选项�分� Windows 和 Shell/Ed 选项�。 将扩展帮助��的帮助�移至扩展标签。为新选项留出空间,并缩短对�框。�者使对�框更适���幕。 (由 Terry Jan Reedy 贡献于 bpo-40468 。) 将缩进空间设置从字体标签移到新的 Windows 标签。 (由 Mark Roseman 和 Terry Jan Reedy 在 bpo-33962 中�供)。

对 .pyi 文件应用语法高亮。 (由 Alex Waygood 和 Terry Jan Reedy 在 bpo-45447 中贡献。)

imaplib¶

现在 IMAP4 和 IMAP4_SSL 的构造器具有�选的 timeout 形�。 并且,现在 open() 方法也具有�选的 timeout 形�包�此修改。 IMAP4_SSL 和 IMAP4_stream 中被�载的方法也应用了此修改。 (由 Donghee Na 在 bpo-38615 中贡献。)

增加了 imaplib.IMAP4.unselect()。 imaplib.IMAP4.unselect() 会释放关�到选定邮箱的�务器资�并将�务器返回到已认�状�。 此命令会执行与 imaplib.IMAP4.close() 相�的动作,区别在于它�会从当�选定邮箱中永久地移除消�。 (由 Donghee Na 在 bpo-40375 中贡献。)

importlib¶

为��与 import 语�的一致性,现在 importlib.util.resolve_name() 对于无效的相对导入�试会引� ImportError 而�是 ValueError。 (由 Ngalim Siregar 在 bpo-37444 中贡献。)

�布���模�对象的导入加载器除了�布�独模�以外现在也�以�布���包。 (由 Dino Viehland 在 bpo-39336 中贡献。)

添加了带有对包数�中�目录支�的 importlib.resources.files() 函数,与 importlib_resources 1.5 版的��端�相匹�。(由 Jason R. Coombs 在 bpo-39791 中贡献。)

�自 importlib_metadata 1.6.1 版的已更新 importlib.metadata。

inspect¶

inspect.BoundArguments.arguments 已从 OrderedDict 改为常规字典。 (由 Inada Naoki 在 bpo-36350 和 bpo-39775 中贡献。)

ipaddress¶

ipaddress 现在支� IPv6 作用域地�(�带有 %<scope_id> �缀的 IPv6 地�)。

IPv6 作用域地��使用 ipaddress.IPv6Address �解�。 作用域的区 ID 如果存在,�通过 scope_id 属性�获�。 (由 Oleksandr Pavliuk 在 bpo-34788 中贡献。)

从 Python 3.9.5 开始 ipaddress 模���接� IPv4 地�字符串中有任何�缀的零。 (由 Christian Heimes 在 bpo-36384 中贡献。)

math¶

对 math.gcd() 函数进行了扩展以处�多个�数。 在之�版本中,它�支�两个�数。 (由 Serhiy Storchaka 在 bpo-39648 中贡献。)

增加了 math.lcm(): 返回指定�数的最�公�数。 (由 Mark Dickinson, Ananthakrishnan 和 Serhiy Storchaka 在 bpo-39479 和 bpo-39648 中贡献。)

增加了 math.nextafter(): 返回从 x 往 y 方�的下一个浮点数值。 (由 Victor Stinner 在 bpo-39288 中贡献。)

增加了 math.ulp(): 返回一个浮点数的最�有效比特�。 (由 Victor Stinner 在 bpo-39310 中贡献。)

multiprocessing¶

multiprocessing.SimpleQueue 类新增了 close() 方法用�显�地关闭队列。 (由 Victor Stinner 在 bpo-30966 中贡献。)

nntplib¶

现在 NNTP 和 NNTP_SSL 当它们的构造器所给定的超时�数为零以防止创建�阻塞套接字时会引� ValueError。 (由 Donghee Na 在 bpo-39259 中贡献。)

os¶

增加了 CLD_KILLED 和 CLD_STOPPED 作为 si_code。 (由 Donghee Na 在 bpo-38493 中贡献。)

对外公开了 Linux 专属的 os.pidfd_open() (bpo-38692) 和 os.P_PIDFD (bpo-38713) 用于文件�述符的进程管�。

现在 os.unsetenv() 函数在 Windows 上也已�用。 (由 Victor Stinner 在 bpo-39413 中贡献。)

现在 os.putenv() 和 os.unsetenv() 函数将总是�用。 (由 Victor Stinner 在 bpo-39395 中贡献。)

增加了 os.waitstatus_to_exitcode() 函数:将等待状�转�为退出�。 (由 Victor Stinner 在 bpo-40094 中贡献。)

pathlib¶

增加了 pathlib.Path.readlink(),其行为类似于 os.readlink()。 (由 Girts Folkmanis 在 bpo-30618 中贡献。)

pdb¶

在 Windows 上 Pdb 现在支� ~/.pdbrc。 (由 Tim Hopper 和 Dan Lidral-Porter 在 bpo-20523 中贡献。)

poplib¶

现在 POP3 和 POP3_SSL 当它们的构造器所给定的超时�数为零以防止创建�阻塞套接字时会引� ValueError。 (由 Donghee Na 在 bpo-39259 中贡献。)

pprint¶

现在 pprint 能美化打� types.SimpleNamespace。 (由 Carl Bordum Hansen 在 bpo-37376 中贡献。)

pydoc¶

文档字符串的显示现在�仅针对类�函数�方法等,也针对任何具有自己的 __doc__ 属性的对象。 (由 Serhiy Storchaka 在 bpo-40257 中贡献。)

random¶

增加了新的 random.Random.randbytes 方法:生��机字节串。 (由 Victor Stinner 在 bpo-40286 中贡献。)

signal¶

对外公开了 Linux 专属的 signal.pidfd_send_signal() 用于�使用文件�述符而� pid 的进程��信�。 (bpo-38712)

smtplib¶

现在 SMTP 和 SMTP_SSL 当它们的构造器所给定的超时�数为零以防止创建�阻塞套接字时会引� ValueError。 (由 Donghee Na 在 bpo-39259 中贡献。)

现在 LMTP 构造器具有一个�选的 timeout 形�。 (由 Donghee Na 在 bpo-39329 中贡献。)

socket¶

现在 socket 模�会在 Linux 4.1 或更高版本上导出 CAN_RAW_JOIN_FILTERS 常�。 (由 Stefan Tatschner 和 Zackery Spytz 在 bpo-25780 中贡献。)

现在 socket 模�会在�到支�的平�上支� CAN_J1939 �议。 (由 Karl Ding 在 bpo-40291 中贡献。)

现在 socket 模�具有 socket.send_fds() 和 socket.recv_fds() 函数。 (由 Joannah Nanjekye, Shinya Okano 和 Victor Stinner 在 bpo-28724 中贡献。)

time¶

在 AIX 上,现在 thread_time() 是使用具有纳秒级精度的 thread_cputime() 实现,而��是�有 10 毫秒精度的 clock_gettime(CLOCK_THREAD_CPUTIME_ID)。 (由 Batuhan Taskaya 在 bpo-40192 中贡献)

sys¶

新增 sys.platlibdir 属性:平�专属库目录的�称。 它被用于构建标准库的路径和已安装扩展模�的路径。 它在大多数平�上等于 "lib"。 在 Fedora 和 SuSE 上,对于 64 �平�它将等于 "lib64"。 (由 Jan Matějek, Matěj Cepl, Charalampos Stratakis 和 Victor Stinner 在 bpo-1294959 中贡献。)

在之�版本中,sys.stderr 在�交互模�时是带�缓冲的。 现在 stderr 默认总是带行缓冲的。 (由 Jendrik Seipp 在 bpo-13601 中贡献。)

tracemalloc¶

增加了 tracemalloc.reset_peak() 用于将跟踪的内存�峰值大�设为当�大�,以测�特定代�段的峰值。 (由 Huon Wilson 在 bpo-40630 中贡献。)

typing¶

PEP 593 引入了一� typing.Annotated 类型以使用上下文专属的元数��装饰现有类型,并将新的 include_extras 形�添加到 typing.get_type_hints() 以在�行时访问元数�。 (由 Till Varoquaux 和 Konstantin Kashin 贡献。)

unicodedata¶

Unicode 数�库已更新到 13.0.0 版。 (bpo-39926)。

venv¶

由 venv 所�供的激活脚本现在总是会使用 __VENV_PROMPT__ 设置的值�一致地指明它们的自定义�示符。 在之�版本中�些脚本会无�件地使用 __VENV_PROMPT__,而�一些脚本�在其�好被设置时(这是默认情况)�会使用,还有的脚本会改用 __VENV_NAME__。 (由 Brett Cannon 在 bpo-37663 中贡献。)

xml¶

当把 xml.etree.ElementTree �列化为 XML 文件时属性内部的空白字符现在将被�留。 ��的行结�符�会�被正规化为 "n"。 这是对于如何解读 XML 规范 2.11 节的相关讨论的最终结果。 (由 Mefistotelis 在 bpo-39011 中贡献。)

性能优化¶

  • 优化了在推导å¼�中为临时å�˜é‡�赋值的惯用方å¼�。 现在推导å¼�中的 for y in [expr] 会与简å�•赋值语å�¥ y = expr 一样快速。 例如:

    sums = [s for s in [0] for x in data for s in [s + x]]

    ��于 := �算符,这个惯用方��会使��泄露到外部作用域中。

    (由 Serhiy Storchaka 在 bpo-32856 中贡献。)

  • 优化了多线程应用中的信å�·å¤„ç�†ã€‚ 如果一个线程ä¸�是获得信å�·çš„主线程,字节ç �求值循环ä¸�会在æ¯�æ�¡å­—节ç �指令上被打断以检查无法被处ç�†çš„æŒ‚èµ·ä¿¡å�·ã€‚ å�ªæœ‰ä¸»è§£é‡Šå™¨çš„主线程能够处ç�†ä¿¡å�·ã€‚

    在之�版本中,字节�求值循环会在��指令上被打断直到主线程处�了信�。 (由 Victor Stinner 在 bpo-40010 上贡献。)

  • 在 FreeBSD 上使用 closefrom() 优化了 subprocess 模å�—。 (由 Ed Maste, Conrad Meyer, Kyle Evans, Kubilay Kocak å’Œ Victor Stinner 在 bpo-38061 中贡献。)

  • 现在 PyLong_FromDouble() 对于 long 范围内值的执行速度æ��å�‡è‡³ 1.87 å€�。 (由 Sergey Fedoseev 在 bpo-37986 中贡献。)

  • 多个 Python 内置类型 (range, tuple, set, frozenset, list, dict) 现在通过使用 PEP 590 vectorcall å��议得到加速。 (由 Donghee Na, Mark Shannon, Jeroen Demeyer å’Œ Petr Viktorin 在 bpo-37207 中贡献。)

  • 当å�¦ä¸€é›†å�ˆè¿œå¤§äºŽåŸºç¡€é›†å�ˆçš„æƒ…况下优化了 difference_update() 的性能。 (由 Evgeny Kapun æ��议,由 Michele Orrù 在 bpo-8425 中贡献代ç �。)

  • Python çš„å°�对象分é…�器 (obmalloc.c) 现在å…�许(至多)一个空ä½�å�¯ç”¨äºŽç«‹å�³é‡�用,而ä¸�必将其返回给 OS。 è¿™å�¯ä»¥é˜²æ­¢ç®€å�•循环中的多余消耗,在æ¯�次迭代中å�¯ä»¥åˆ›å»ºå’Œé”€æ¯�全新的空ä½�。 (由 Tim Peters 在 bpo-37257 中贡献。)

  • 浮点数è¿�算中的 floor division 现在会有更好的性能。 并且此è¿�ç®—çš„ ZeroDivisionError 消æ�¯ä¹ŸèŽ·å¾—äº†æ›´æ–°ã€‚ (由 Donghee Na 在 bpo-39434 中贡献。)

  • 使用 UTF-8 å’Œ ascii ç¼–è§£ç �器解ç �短 ASCII 字符串现在会加快大约 15%。 (由 Inada Naoki 在 bpo-37348 中贡献。)

以下是对从 Python 3.4 到 Python 3.9 的����情况的总结:

Python version                       3.4     3.5     3.6     3.7     3.8    3.9
--------------                       ---     ---     ---     ---     ---    ---

Variable and attribute read access:
    read_local                       7.1     7.1     5.4     5.1     3.9    3.9
    read_nonlocal                    7.1     8.1     5.8     5.4     4.4    4.5
    read_global                     15.5    19.0    14.3    13.6     7.6    7.8
    read_builtin                    21.1    21.6    18.5    19.0     7.5    7.8
    read_classvar_from_class        25.6    26.5    20.7    19.5    18.4   17.9
    read_classvar_from_instance     22.8    23.5    18.8    17.1    16.4   16.9
    read_instancevar                32.4    33.1    28.0    26.3    25.4   25.3
    read_instancevar_slots          27.8    31.3    20.8    20.8    20.2   20.5
    read_namedtuple                 73.8    57.5    45.0    46.8    18.4   18.7
    read_boundmethod                37.6    37.9    29.6    26.9    27.7   41.1

Variable and attribute write access:
    write_local                      8.7     9.3     5.5     5.3     4.3    4.3
    write_nonlocal                  10.5    11.1     5.6     5.5     4.7    4.8
    write_global                    19.7    21.2    18.0    18.0    15.8   16.7
    write_classvar                  92.9    96.0   104.6   102.1    39.2   39.8
    write_instancevar               44.6    45.8    40.0    38.9    35.5   37.4
    write_instancevar_slots         35.6    36.1    27.3    26.6    25.7   25.8

Data structure read access:
    read_list                       24.2    24.5    20.8    20.8    19.0   19.5
    read_deque                      24.7    25.5    20.2    20.6    19.8   20.2
    read_dict                       24.3    25.7    22.3    23.0    21.0   22.4
    read_strdict                    22.6    24.3    19.5    21.2    18.9   21.5

Data structure write access:
    write_list                      27.1    28.5    22.5    21.6    20.0   20.0
    write_deque                     28.7    30.1    22.7    21.8    23.5   21.7
    write_dict                      31.4    33.3    29.3    29.2    24.7   25.4
    write_strdict                   28.4    29.9    27.5    25.2    23.1   24.5

Stack (or queue) operations:
    list_append_pop                 93.4   112.7    75.4    74.2    50.8   50.6
    deque_append_pop                43.5    57.0    49.4    49.2    42.5   44.2
    deque_append_popleft            43.7    57.3    49.7    49.7    42.8   46.4

Timing loop:
    loop_overhead                    0.5     0.6     0.4     0.3     0.3    0.3

以上结果是由以下��访问基准测试脚本所生�的: Tools/scripts/var_access_benchmark.py。 该基准测试脚本以纳秒为��显示时间。 基准测试数�是在一� Intel® Core™ i7-4960HQ 处�器 �行从 python.org 获�的 macOS 64 �编译版本所得到的。

弃用¶

  • distutils çš„ bdist_msi 命令现在已被弃用,请改用 bdist_wheel (wheel 包)。 (由 Hugo van Kemenade 在 bpo-39586 中贡献。)

  • ç›®å‰� math.factorial() 接å�—具有é�žè´Ÿæ•´æ•°å€¼çš„ float 实例 (如 5.0)。 对于é�žæ•´æ•°å’Œè´Ÿæµ®ç‚¹æ•°å®ƒä¼šå¼•å�‘ ValueError。 此行为现在已被弃用。 在未æ�¥çš„ Python 版本中对所有浮点数都将引å�‘ TypeError。 (由 Serhiy Storchaka 在 bpo-37315 中贡献。)

  • parser å’Œ symbol 模å�—已被弃用并将在未æ�¥çš„ Python 版本中移除。 对于大多数用例,用户都å�¯ä»¥ä½¿ç”¨ ast 模å�—æ�¥æŽ§åˆ¶æŠ½è±¡è¯­æ³•æ ‘ (AST) 的生æˆ�和编译阶段。

  • 公有 C API 函数 PyParser_SimpleParseStringFlags(), PyParser_SimpleParseStringFlagsFilename(), PyParser_SimpleParseFileFlags() å’Œ PyNode_Compile() 已被弃用并将在 Python 3.10 中与旧的解æž�器一起被移除。

  • 在布尔è¿�算中使用 NotImplemented 已被弃用,因为它几乎必定是ä¸�正确的富比较è¿�算符实现的结果。 它将在未æ�¥çš„ Python 版本中引å�‘ TypeError。 (由 Josh Rosenberg 在 bpo-35712 中贡献。)

  • random 模å�—ç›®å‰�接å�—任何å�¯å“ˆå¸Œç±»åž‹ä½œä¸ºå�¯èƒ½çš„ç§�å­�值。 ä¸�幸的是,æŸ�些这样的类型并ä¸�ä¿�è¯�具有确定性的哈希值。 在 Python 3.9 之å�Žï¼Œè¯¥æ¨¡å�—å°†é™�定其ç§�å­�值为 None, int, float, str, bytes 以å�Š bytearray。

  • 打开 GzipFile 文件用于写入而ä¸�指定 mode å�‚数的特性已被弃用。 在未æ�¥çš„ Python 版本中将总是默认打开用于读å�–。 在打开文件用于写入时请指定 mode å�‚数以é�™é»˜ç›¸å…³è­¦å‘Šä¿¡æ�¯ã€‚ (由 Serhiy Storchaka 在 bpo-28286 中贡献。)

  • 弃用了 _tkinter.TkappType çš„ split() 方法而改用 splitlist() 方法,此方法具有更稳定且å�¯é¢„测的行为。 (由 Serhiy Storchaka 在 bpo-38371 中贡献。)

  • å°†å��程对象显å¼�传递给 asyncio.wait() çš„å�šæ³•å·²è¢«å¼ƒç”¨å¹¶ä¸”å°†åœ¨ 3.11 版中被移除。 (由 Yury Selivanov å’Œ Kyle Stanley 在 bpo-34790 中贡献。)

  • binhex4 å’Œ hexbin4 标准现已被弃用。 binhex 模å�—和下列 binascii 函数现已被弃用:

    • b2a_hqx(), a2b_hqx()

    • rlecode_hqx(), rledecode_hqx()

    (由 Victor Stinner 在 bpo-39353 中贡献。)

  • ast ç±» slice, Index å’Œ ExtSlice 被视为已弃用并将在未æ�¥çš„ Python 版本中被移除。 应当使用 value 本身而ä¸�å†�是 Index(value)。 应当使用 Tuple(slices, Load()) 而ä¸�å†�是 ExtSlice(slices)。 (由 Serhiy Storchaka 在 bpo-34822 中贡献。)

  • ast ç±» Suite, Param, AugLoad å’Œ AugStore 被视为已弃用并将在未æ�¥çš„ Python 版本中被移除。 它们ä¸�会被解æž�器所生æˆ�且ä¸�会被 Python 3 中的代ç �生æˆ�器所接å�—。 (由 Batuhan Taskaya 在 bpo-39639 å’Œ bpo-39969 中以å�Š Serhiy Storchaka 在 bpo-39988 中贡献。)

  • PyEval_InitThreads() å’Œ PyEval_ThreadsInitialized() 函数现已被弃用并将在 Python 3.11 中移除。 现在调用 PyEval_InitThreads() 将没有任何效果。 自 Python 3.7 èµ· GIL 会由 Py_Initialize() åˆ�始化。(由 Victor Stinner 在 bpo-39877 中贡献。)

  • ä¼ å…¥ None 作为 shlex.split() 函数的第一个å�‚æ•°çš„å�šæ³•å·²è¢«å¼ƒç”¨ã€‚ (由 Zackery Spytz 在 bpo-33262 中贡献。)

  • smtpd.MailmanProxy() 现在已被弃用,因为它在没有外部模å�— mailman 的情况下无法使用。 (由 Samuel Colvin 在 bpo-35800 中贡献。)

  • 现在 lib2to3 模å�—å°†å�‘出 PendingDeprecationWarning。 Python 3.9 已切æ�¢åˆ° PEG è§£æž�器 (å�‚è§� PEP 617),Python 3.10 å�¯ä»¥ä¼šåŒ…å�« lib2to3 çš„ LL(1) è§£æž�器所ä¸�能解æž�的新语法。 lib2to3 模å�—å�¯èƒ½ä¼šåœ¨æœªæ�¥çš„ Python 版本中被移出标准库。 请考虑使用第三方替æ�¢ä¾‹å¦‚ LibCST 或 parso。 (由 Carl Meyer 在 bpo-40360 中贡献。)

  • random.shuffle() çš„ random å½¢å�‚已被弃用。 (由 Raymond Hettinger 在 bpo-40465 中贡献。)

移除¶

  • unittest.mock.__version__ 上的错误版本已ç»�被移除。

  • nntplib.NNTP: xpath() å’Œ xgtitle() 方法已被移除。 这些方法自 Python 3.3 起已被弃用。 一般æ�¥è¯´ï¼Œè¿™äº›æ‰©å±•都ä¸�å†�为 NNTP æœ�务管ç�†ç¨‹åº�所支æŒ�或å�¯ç”¨ã€‚ 对于 xgtitle(),请改用 nntplib.NNTP.descriptions() 或 nntplib.NNTP.description()。 (由 Donghee Na 在 bpo-39366 中贡献。)

  • array.array: tostring() å’Œ fromstring() 方法已被移除。 它们分别是 tobytes() å’Œ frombytes() 的别å��,自 Python 3.2 起已被弃用。 (由 Victor Stinner 在 bpo-38916 中贡献。)

  • 未写入文档的 sys.callstats() 函数已被移除。 自 Python 3.7 起它就已被弃用并且总是会返回 None。 它需è¦�一个特殊的构建选项 CALL_PROFILE 而该选项在 Python 3.7 中已被移除。 (由 Victor Stinner 在 bpo-37414 中贡献。)

  • sys.getcheckinterval() å’Œ sys.setcheckinterval() 函数已被移除。 它们自 Python 3.2 起已被弃用。 请改用 sys.getswitchinterval() å’Œ sys.setswitchinterval()。 (由 Victor Stinner 在 bpo-37392 中贡献。)

  • C 函数 PyImport_Cleanup() 已被移除。 它原本的文档为: "清空模å�—表。 ä»…é™�内部使用。" (由 Victor Stinner 在 bpo-36710 中贡献。)

  • _dummy_thread å’Œ dummy_threading 模å�—已被移除。 这些模å�—自 Python 3.7 起已被弃用,它们需è¦�线程支æŒ�。 (由 Victor Stinner 在 bpo-37312 中贡献。)

  • aifc.open() 的别å�� aifc.openfp(),sunau.open() 的别å�� sunau.openfp(),以å�Š wave.open() 的别å�� wave.openfp() 已被移除。 它们自 Python 3.7 起已被弃用。 (由 Victor Stinner 在 bpo-37320 中贡献。)

  • threading.Thread çš„ isAlive() 方法已被移除。 它自 Python 3.8 起已被弃用。 请改用 is_alive()。 (由 Donghee Na 在 bpo-37804 中贡献。)

  • ElementTree 模å�—中 ElementTree å’Œ Element 等类的 getchildren() å’Œ getiterator() 方法已被移除。 它们在 Python 3.2 中已被弃用。 请使用 iter(x) 或 list(x) 替代 x.getchildren() 并用 x.iter() 或 list(x.iter()) 替代 x.getiterator()。 (由 Serhiy Storchaka 在 bpo-36543 中贡献。)

  • æ—§çš„ plistlib API 已被移除,它自 Python 3.4 起已被弃用。 请使用 load(), loads(), dump() å’Œ dumps() 等函数。 此外,use_builtin_types å½¢å�‚已被移除而总是会使用 bytes 对象。 (由 Jon Janzen 在 bpo-36409 中贡献。)

  • C 函数 PyGen_NeedsFinalizing 已被移除。 它未被写入文档ã€�未ç»�测试,且自 PEP 442 实现之å�Žæœªåœ¨ CPython 的任何地方被使用。 ç”± Joannah Nanjekye æ��供补ä¸�。 (由 Joannah Nanjekye 在 bpo-15088 中贡献。)

  • 自 Python 3.1 起被弃用的别å�� base64.encodestring() å’Œ base64.decodestring() 已被移除:请改用 base64.encodebytes() å’Œ base64.decodebytes()。 (由 Victor Stinner 在 bpo-39351 中贡献。)

  • fractions.gcd() 函数已被移除,它自 Python 3.5 起被弃用 (bpo-22486):请改用 math.gcd()。 (由 Victor Stinner 在 bpo-39350 中贡献。)

  • bz2.BZ2File çš„ buffering å½¢å�‚已被移除。 它自 Python 3.0 èµ·å�³è¢«å¿½ç•¥ï¼Œä½¿ç”¨å®ƒå°†ä¼šå¼•å�‘ DeprecationWarning。 请传入一个打开文件对象æ�¥æŽ§åˆ¶æ–‡ä»¶çš„æ‰“开方å¼�。 (由 Victor Stinner 在 bpo-39357 中贡献。)

  • json.loads() çš„ encoding å½¢å�‚已被移除。 它在 Python 3.1 中已被弃用和忽略;自 Python 3.8 起使用它将会引å�‘ DeprecationWarning。 (由 Inada Naoki 在 bpo-39377 中贡献。)

  • with (await asyncio.lock): å’Œ with (yield from asyncio.lock): 语å�¥å·²ä¸�å†�å�—支æŒ�,请改用 async with lock。 asyncio.Condition å’Œ asyncio.Semaphore 也å�Œæ ·å¦‚此。 (由 Andrew Svetlov 在 bpo-34793 中贡献。)

  • sys.getcounts() 函数,-X showalloccount 命令行选项以å�Š C 结构体 PyConfig çš„ show_alloc_count 字段已被移除。 它们需è¦�使用定义了 COUNT_ALLOCS å®�的特殊 Python 编译版本。 (由 Victor Stinner 在 bpo-39489 中贡献。)

  • typing.NamedTuple 类的 _field_types 属性已被移除。 它自 Python 3.8 起已被弃用。 请改用 __annotations__ 属性。 (由 Serhiy Storchaka 在 bpo-40182 中贡献。)

  • symtable.SymbolTable.has_exec() 方法已被移除。 它自 2006 年起已被弃用,当被调用时仅会返回 False。 (由 Batuhan Taskaya 在 bpo-40208 中贡献。)

  • asyncio.Task.current_task() å’Œ asyncio.Task.all_tasks() 已被移除。 它们自 Python 3.7 起已被弃用,你å�¯ä»¥æ”¹ç”¨ asyncio.current_task() å’Œ asyncio.all_tasks()。 (由 Rémi Lapeyre 在 bpo-40967 中贡献。)

  • html.parser.HTMLParser 类的 unescape() 方法已被移除(它自 Python 3.4 起已被弃用)。 应当使用 html.unescape() æ�¥å°†å­—符引用转æ�¢ä¸ºå¯¹åº”çš„ unicode 字符。

移�到 Python 3.9¶

本节列出了先��述的更改以��能需�更改代�的其他错误修正.

Python API 的�化¶

  • __import__() å’Œ importlib.util.resolve_name() 现在会引å�‘ ImportError å�–代之å‰�所引å�‘çš„ ValueError。 æ�•获特定异常类型并å�Œæ—¶æ”¯æŒ� Python 3.9 和更早版本的调用者将需è¦�使用 except (ImportError, ValueError): æ�¥å�Œæ—¶æ�•获两者。

  • venv 激活脚本ä¸�å†�å°† __VENV_PROMPT__ 被设为 "" 的情况作为特例处ç�†ã€‚

  • select.epoll.unregister() 方法ä¸�会å†�忽略 EBADF 错误。 (由 Victor Stinner 在 bpo-39239 中贡献。)

  • bz2.BZ2File çš„ compresslevel å½¢å�‚å·²æˆ�为仅é™�关键字形å�‚,因为 buffering å½¢å�‚已被移除。 (由 Victor Stinner 在 bpo-39357 中贡献。)

  • 简化了 AST 的抽å�–æ“�作。 简å�•索引将以它们的值æ�¥ä»£è¡¨ï¼Œæ‰©å±•切片将以元组形å¼�æ�¥ä»£è¡¨ã€‚ Index(value) 将返回 value 本身,ExtSlice(slices) 将返回 Tuple(slices, Load())。 (由 Serhiy Storchaka 在 bpo-34822 中贡献。)

  • 当使用了 -E 或 -I 命令行å�‚æ•°æ—¶ importlib 模å�—现在会忽略 PYTHONCASEOK 环境å�˜é‡�。

  • encoding å½¢å�‚已作为仅é™�关键字形å�‚被添加到 ftplib.FTP å’Œ ftplib.FTP_TLS 类,并且默认编ç �æ ¼å¼�ç”± Latin-1 改为 UTF-8 以é�µå¾ª RFC 2640。

  • asyncio.loop.shutdown_default_executor() 已被添加到 AbstractEventLoop,这æ„�味ç�€ç»§æ‰¿è‡ªå®ƒçš„æ›¿ä»£äº‹ä»¶å¾ªçŽ¯åº”å½“å®šä¹‰æ­¤æ–¹æ³•ã€‚ (由 Kyle Stanley 在 bpo-34037 中贡献。)

  • 更新了 __future__ 模å�—中未æ�¥ç‰¹æ€§æ——标的常é‡�值以防止与编译器旗标相冲çª�。 在之å‰�版本中 PyCF_ALLOW_TOP_LEVEL_AWAIT 会与 CO_FUTURE_DIVISION å�‘生冲çª�。 (由 Batuhan Taskaya 在 bpo-39562 中贡献。)

  • array('u') 现在使用 wchar_t 作为 C 类型而ä¸�是 Py_UNICODE。 这一更改ä¸�会影å“�其行为,因为自 Python 3.3 èµ· Py_UNICODE 就是 wchar_t 的别å��。 (由 Inada Naoki 在 bpo-34538 中贡献。)

  • 现在 logging.getLogger() API 当传入å��ç§° 'root' 时将返回根日志记录器,而在之å‰�它则返回一个å��为 'root' çš„é�žæ ¹æ—¥å¿—记录器。 è¿™å�¯èƒ½ä¼šå½±å“�到用户代ç �明确希望使用一个å��为 'root' çš„é�žæ ¹æ—¥å¿—记录器,或在æŸ�个å��为 'root.py' 的最高层级模å�—中使用 logging.getLogger(__name__) æ�¥å®žä¾‹åŒ–日志记录器的情况。 (由 Vinay Sajip 在 bpo-37742 中贡献。)

  • 现在 PurePath 的拆分处ç�†å½“ä¼ å…¥ str 或 PurePath 的实例以外的对象时会返回 NotImplemented 而ä¸�是引å�‘ TypeError。 这将å…�许创建ä¸�继承自上述类型的兼容类。 (由 Roger Aiudi 在 bpo-34775 中贡献。)

  • 从 Python 3.9.5 开始 ipaddress 模å�—ä¸�å†�接å�— IPv4 地å�€å­—符串中有任何å‰�缀的零。 å‰�缀的零有歧义且会被æŸ�些库解读为八进制数字。 例如旧版函数 socket.inet_aton() 就瘵å‰�缀的零视为八进制数字。 最新 inet_pton() çš„ glibc 实现则ä¸�接å�—任何å‰�缀的零。 (由 Christian Heimes 在 bpo-36384 中贡献)。

  • codecs.lookup() 现在会以与 encodings.normalize_encoding() 相å�Œçš„æ–¹å¼�正规化编ç �æ ¼å¼�å��称,ä¸�å�Œä¹‹å¤„在于 codecs.lookup() 还会将å��称转æ�¢ä¸ºå°�写形å¼�。 例如 "latex+latin1" 编写格å¼�å��称现在会被正规化为 "latex_latin1"。 (由 Jordon Xu 在 bpo-37751 中贡献。)

C API 的�化¶

  • Instances of 堆分é…�类型 的实例(例如使用 PyType_FromSpec() 和类似 API 创建的实例)自 Python 3.8 起会带有一个对其类型对象的引用。 正如 Python 3.8 çš„ "C API çš„å�˜åŒ–" 部分所述,对于大多数情况æ�¥è¯´ï¼Œè¿™åº”当ä¸�会有任何副作用,但对于具有自定义 tp_traverse 函数的类型æ�¥è¯´ï¼Œåˆ™è¦�ç¡®ä¿�所有堆分é…�类型的自定义 tp_traverse 函数å�¯è®¿é—®å¯¹è±¡çš„类型。

    示例:

    int
    foo_traverse(foo_struct *self, visitproc visit, void *arg) {
    // Rest of the traverse function
    #if PY_VERSION_HEX >= 0x03090000
        // This was not needed before Python 3.9 (Python issue 35810 and 40217)
        Py_VISIT(Py_TYPE(self));
    #endif
    }
    

    如果你的�历函数委托给了其基类(或其他类)的 tp_traverse,则�确� Py_TYPE(self) �被访问一次。 请注�应当�有 堆类型 �访问 tp_traverse 中的类型。

    举例�说,如果你的 tp_traverse 函数包括以下内容:

    base->tp_traverse(self, visit, arg)
    

    则�添加:

    #if PY_VERSION_HEX >= 0x03090000
        // This was not needed before Python 3.9 (bpo-35810 and bpo-40217)
        if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
            // a heap type's tp_traverse already visited Py_TYPE(self)
        } else {
            Py_VISIT(Py_TYPE(self));
        }
    #else
    

    (�阅 bpo-35810 和 bpo-40217 了解更多信�。)

  • PyEval_CallObject, PyEval_CallFunction, PyEval_CallMethod å’Œ PyEval_CallObjectWithKeywords 函数已被弃用。 请改用 PyObject_Call() å�Šå…¶å�˜åŒ–å½¢å¼�。 (详情å�‚è§� bpo-29548。)

CPython 字节�的改�¶

  • 添加了 LOAD_ASSERTION_ERROR æ“�作ç �用于处ç�† assert 语å�¥ã€‚ 在之å‰�的版本中,如果 AssertionError 异常被å±�蔽则 assert 语å�¥å°†ä¸�能正常è¿�作。 (由 Zackery Spytz 在 bpo-34880 中贡献。)

  • COMPARE_OP æ“�作ç �已被拆分为四个å�•独指令:

    • COMPARE_OP 用于富比较

    • IS_OP 用于 'is' å’Œ 'is not' 检测

    • CONTAINS_OP 用于 'in' å’Œ 'not in' 检测

    • JUMP_IF_NOT_EXC_MATCH 用于检查 'try-except' 语å�¥ä¸­çš„异常。

    (由 Mark Shannon 在 bpo-39156 中贡献。)

构建的改�¶

  • å�‘ configure 脚本添加了 --with-platlibdir 选项:平å�°ä¸“属库目录的å��称,ä¿�存在新的 sys.platlibdir 属性中。 请å�‚阅 sys.platlibdir 属性了解更多信æ�¯ã€‚ (由 Jan MatÄ›jek, MatÄ›j Cepl, Charalampos Stratakis å’Œ Victor Stinner 在 bpo-1294959 中贡献。)

  • COUNT_ALLOCS 特殊构建å®�已被移除。 (由 Victor Stinner 在 bpo-39489 中贡献。)

  • 在é�ž Windows å¹³å�°ä¸Šï¼ŒçŽ°åœ¨éœ€è¦�用 setenv() å’Œ unsetenv() 函数æ�¥æž„建 Python。 (由 Victor Stinner 在 bpo-39395 中贡献。)

  • 在é�ž Windows å¹³å�°ä¸Šï¼Œåˆ›å»º bdist_wininst 安装器现在已ä¸�å�—官方支æŒ�。 (详情å�‚è§� bpo-10945。)

  • 当在 macOS 上用æº�代ç �编译 Python 时,_tkinter 现在会链接到é�žç³»ç»Ÿçš„ Tcl å’Œ Tk 框架,如果它们被安装到 /Library/Frameworks çš„è¯�,就如在较旧的 macOS å�‘行版上的情况一样。 如果通过使用 --enable-universalsdk 或 -isysroot 显å¼�地é…�置了 macOS SDK,则å�ªä¼šæ�œç´¢ SDK 本身。 默认行为ä»�ç„¶å�¯ä»¥é€šè¿‡ --with-tcltk-includes å’Œ --with-tcltk-libs æ�¥è¦†ç›–。 (由 Ned Deily 在 bpo-34956 中贡献。)

  • Python 现在å�¯ä»¥é’ˆå¯¹ Windows 10 ARM64 进行编译。 (由 Steve Dower 在 bpo-33125 中贡献。)

  • 现在当使用 --pgo 时一些å�•独的测试会被跳过。 这些测试显著增加了 PGO 任务的时间并且å�¯èƒ½æ— åŠ©äºŽæ��å�‡æœ€ç»ˆå�¯æ‰§è¡Œæ–‡ä»¶çš„优化程度。 这样能使任务加速大约 15 å€�。 è¿�行完整的å�•元测试是很慢的。 这个改å�˜å�¯èƒ½å¯¼è‡´ä¼˜åŒ–程åº�ç¨�差的构建,因为将被执行的代ç �分支ä¸�够多。 如果你愿æ„�等待更缓慢的构建,则å�¯ä»¥ä½¿ç”¨ ./configure [..] PROFILE_TASK="-m test --pgo-extended" æ�¥æ�¢å¤�旧版本的行为。 我们ä¸�ä¿�è¯�哪个 PGO 任务集能产生更快的构建。 关心此问题的用户应当自行è¿�行相关基准测试,因为结果å�¯èƒ½å�–决于具体环境ã€�工作负载以å�Šç¼–译工具链。 (请å�‚阅 bpo-36044 å’Œ bpo-37707 了解详情。)

C API 的改�¶

新的特性¶

  • PEP 573: 添加了 PyType_FromModuleAndSpec() 用于将模å�—与类关è�”;添加了 PyType_GetModule() å’Œ PyType_GetModuleState() 用于获å�–模å�—å�Šå…¶çжæ€�;以å�Š PyCMethod å’Œ METH_METHOD 用于å…�许一个方法访问其定义所在的类。 (由 Marcel Plch å’Œ Petr Viktorin 在 d:issue:38787 中贡献。)

  • 增加了 PyFrame_GetCode() 函数:获å�–帧代ç �。 增加了 PyFrame_GetBack() 函数:获å�–帧的下一个外部帧。 (由 Victor Stinner 在 bpo-40421 中贡献。)

  • å°† PyFrame_GetLineNumber() 添加到å�—é™�çš„ C API。 (由 Victor Stinner 在 bpo-40421 中贡献。)

  • 增加了 PyThreadState_GetInterpreter() å’Œ PyInterpreterState_Get() 函数用于获å�–解释器。 增加了 PyThreadState_GetFrame() 函数用于获å�– Python 线程状æ€�的当å‰�帧。 增加了 PyThreadState_GetID() 函数:获å�– Python 线程状æ€�的唯一标识符。 (由 Victor Stinner 在 bpo-39947 中贡献。)

  • 将新的公有 PyObject_CallNoArgs() 函数添加到 C API,该函数å�¯ä¸�带任何å�‚数调用一个 Python å�¯è°ƒç”¨å¯¹è±¡ã€‚ 它是ä¸�带å�‚数调用 Python å�¯è°ƒç”¨å¯¹è±¡æœ€æœ‰æ•ˆçŽ‡çš„æ–¹å¼�。 (由 Victor Stinner 在 bpo-37194 中贡献。)

  • å�—é™� C API 中的改å�˜ï¼ˆå¦‚果定义了 Py_LIMITED_API å®�):

    • æ��ä¾› Py_EnterRecursiveCall() å’Œ Py_LeaveRecursiveCall() 作为常规函数用于å�—é™� API。 在之å‰�版本中是使用å®�定义,但这些å®�ä¸�能与无法访问 PyThreadState.recursion_depth 字段的å�—é™� C API 一å�Œç¼–译(该结构体在å�—é™� C API 中是ä¸�é€�明的)。

    • PyObject_INIT() å’Œ PyObject_INIT_VAR() å·²æˆ�为常规“ä¸�é€�明â€�函数以éš�è—�实现细节。

    (由 Victor Stinner 在 bpo-38644 和 bpo-39542 中贡献。)

  • 增加了 PyModule_AddType() 函数以å��助将类型加入到模å�—中。 (由 Donghee Na 在 bpo-40024 中贡献。)

  • å°† PyObject_GC_IsTracked() å’Œ PyObject_GC_IsFinalized() 函数添加到公有 API 以å…�许分别查询 Python 对象当å‰�是正在被追踪还是已ç»�被垃圾回收器所终结。 (由 Pablo Galindo Salgado 在 bpo-40241 中贡献。)

  • 增加了 _PyObject_FunctionStr() 以获å�–函数类对象的用户å�‹å¥½çš„表示形å¼�。 (由 Jeroen Demeyer 在 bpo-37645 中修正。)

  • 增加了 PyObject_CallOneArg() 用于调用具有一个ä½�ç½®å�‚数的对象(由 Jeroen Demeyer 在 bpo-37483 中修正。)

移�到 Python 3.9¶

  • PyInterpreterState.eval_frame (PEP 523) 现在需è¦�有新的强制性形å�‚ tstate (PyThreadState*)。 (由 Victor Stinner 在 bpo-38500 中贡献。)

  • 扩展模å�—: PyModuleDef çš„ m_traverse, m_clear å’Œ m_free 等函数在模å�—状æ€�被请求但尚未被分é…�æ—¶å°†ä¸�会å†�被调用。 è¿™ç§�情况出现在模å�—被创建之å�Žä¸”模å�—被执行 (Py_mod_exec 函数) 之å‰�的时刻。 更准确地说,这些函数在 m_size 大于 0 并且模å�—状æ€�(å�³ PyModule_GetState() 的返回值)为 NULL æ—¶å°†ä¸�会被调用。

    没有模�状�的扩展模� (m_size <= 0) �会�到影�。

  • 现在如果 Py_AddPendingCall() 是在å­�解释器内部被调用,该函数会被排入å­�解释器的调用日程,而ä¸�是由主解释器调用。 æ¯�个å­�解释器现在都拥有它们自己的调用日程列表。 (由 Victor Stinner 在 bpo-39984 中贡献。)

  • 当 -E 选项被使用 (如果 PyConfig.use_environment 设为 0) æ—¶å°†ä¸�å†�使用 Windows 注册表æ�¥åˆ�始化 sys.path。 这会影å“�在 Windows 上嵌入 Python çš„æ“�作。 (由 Zackery Spytz 在 bpo-8901 中贡献。)

  • 全局å�˜é‡� PyStructSequence_UnnamedField 现在为常é‡�并且指å�‘一个字符串常é‡�。 (由 Serhiy Storchaka 在 bpo-38650 中贡献。)

  • 现在 PyGC_Head 结构是ä¸�é€�明的。 它å�ªåœ¨å†…部 C API (pycore_gc.h) 中定义。 (由 Victor Stinner 在 bpo-40241 中贡献。)

  • Py_UNICODE_COPY, Py_UNICODE_FILL, PyUnicode_WSTR_LENGTH, PyUnicode_FromUnicode(), PyUnicode_AsUnicode(), _PyUnicode_AsUnicode å’Œ PyUnicode_AsUnicodeAndSize() 在 C 中已被标记为弃用。 自 Python 3.3 起它们就已被 PEP 393 弃用。 (由 Inada Naoki 在 bpo-36346 中贡献。)

  • Py_FatalError() 函数会被一个自动记录当å‰�函数å��ç§°çš„å®�所替代,除é�žå·²å®šä¹‰äº† Py_LIMITED_API å®�。 (由 Victor Stinner 在 bpo-39882 中贡献。)

  • vectorcall å��议现在è¦�求调用者å�ªä¼ å…¥å­—符串作为键å��。 (请å�‚阅 bpo-37540 了解详情。)

  • 多个å®�和函数的实现细节现在已被éš�è—�:

    • PyObject_IS_GC() å®�已被转æ�¢ä¸ºå‡½æ•°ã€‚

    • PyObject_NEW() å®�å·²æˆ�为 PyObject_New å®�的别å��,而 PyObject_NEW_VAR() å®�å·²æˆ�为 PyObject_NewVar å®�的别å��。 它们ä¸�å†�直接访问 PyTypeObject.tp_basicsize æˆ�员。

    • PyObject_GET_WEAKREFS_LISTPTR() å®�已被转æ�¢ä¸ºå‡½æ•°ï¼šè¯¥å®�会直接访问 PyTypeObject.tp_weaklistoffset æˆ�员。

    • PyObject_CheckBuffer() å®�已被转æ�¢ä¸ºå‡½æ•°ï¼šè¯¥å®�会直接访问 PyTypeObject.tp_as_buffer æˆ�员。

    • 现在 PyIndex_Check() 总是被声明为ä¸�é€�明函数以éš�è—�实现细节;PyIndex_Check() å®�已被移除。 该å®�会直接访问 PyTypeObject.tp_as_number æˆ�员。

    (详情请�阅 bpo-40170。)

移除¶

  • pyfpe.h çš„ PyFPE_START_PROTECT() å’Œ PyFPE_END_PROTECT() å®�已从å�—é™�çš„ C API 中被排除。 (由 Victor Stinner 在 bpo-38835 中贡献。)

  • PyTypeObject çš„ tp_print 空ä½�已被移除。 它在 Python 2.7 å�Šä¹‹å‰�的版本中被用æ�¥å°†å¯¹è±¡æ‰“å�°åˆ°æ–‡ä»¶ã€‚ 自 Python 3.0 起,它已被忽略并且ä¸�å†�使用。 (由 Jeroen Demeyer 在 bpo-36974 中贡献。)

  • å�—é™� C API 中的改å�˜ï¼ˆå¦‚果定义了 Py_LIMITED_API å®�):

    • 以下函数已从å�—é™� C API 中排除:

      • PyThreadState_DeleteCurrent() (由 Joannah Nanjekye 在 bpo-37878 中贡献。)

      • _Py_CheckRecursionLimit

      • _Py_NewReference()

      • _Py_ForgetReference()

      • _PyTraceMalloc_NewReference()

      • _Py_GetRefTotal()

      • 在å�—é™� C API 中从未使用的垃圾箱机制。

      • PyTrash_UNWIND_LEVEL

      • Py_TRASHCAN_BEGIN_CONDITION

      • Py_TRASHCAN_BEGIN

      • Py_TRASHCAN_END

      • Py_TRASHCAN_SAFE_BEGIN

      • Py_TRASHCAN_SAFE_END

    • 已将下列函数和定义移至内部 C API:

      • _PyDebug_PrintTotalRefs()

      • _Py_PrintReferences()

      • _Py_PrintReferenceAddresses()

      • _Py_tracemalloc_config

      • _Py_AddToAllObjects() (Py_TRACE_REFS 构建专属)

    (由 Victor Stinner 在 bpo-38644 和 bpo-39542 中贡献。)

  • 移除了 _PyRuntime.getframe é’©å­�并移除了 _PyThreadState_GetFrame å®�,该å®�是 _PyRuntime.getframe 的一个别å��。 它们仅由内部 C API 对外公开。 å�Œæ ·åœ°ç§»é™¤äº† PyThreadFrameGetter 类型。 (由 Victor Stinner 在 bpo-39946 中贡献。)

  • 从 C API 移除了下列函数。 请显å¼�地调用 PyGC_Collect() æ�¥æ¸…空所有自由列表。 (由 Inada Naoki å’Œ Victor Stinner 在 bpo-37340, bpo-38896 å’Œ bpo-40428 中贡献。)

    • PyAsyncGen_ClearFreeLists()

    • PyContext_ClearFreeList()

    • PyDict_ClearFreeList()

    • PyFloat_ClearFreeList()

    • PyFrame_ClearFreeList()

    • PyList_ClearFreeList()

    • PyMethod_ClearFreeList() å’Œ PyCFunction_ClearFreeList(): 绑定方法对象的自由列表已被移除。

    • PySet_ClearFreeList(): 集å�ˆè‡ªç”±åˆ—表已在 Python 3.4 中被移除。

    • PyTuple_ClearFreeList()

    • PyUnicode_ClearFreeList(): Unicode 自由列表已在 Python 3.3 中被移除。

  • 移除了 _PyUnicode_ClearStaticStrings() 函数。 (由 Victor Stinner 在 bpo-39465 中贡献。)

  • 移除了 Py_UNICODE_MATCH。 它已被 PEP 393 所弃用,并自 Python 3.3 èµ·ä¸�å†�å�¯ç”¨ã€‚ å�¯ä»¥æ”¹ç”¨ PyUnicode_Tailmatch() 函数。 (由 Inada Naoki 在 bpo-36346 中贡献。)

  • 清除了已定义但未实现的接å�£çš„头文件。 被移除了公共 API 符å�·æœ‰: _PyBytes_InsertThousandsGroupingLocale, _PyBytes_InsertThousandsGrouping, _Py_InitializeFromArgs, _Py_InitializeFromWideArgs, _PyFloat_Repr, _PyFloat_Digits, _PyFloat_DigitsInit, PyFrame_ExtendStack, _PyAIterWrapper_Type, PyNullImporter_Type, PyCmpWrapper_Type, PySortWrapper_Type, PyNoArgsFunction。 (由 Pablo Galindo Salgado 在 bpo-39372 中贡献。)

Python 3.9.1 中的���化¶

typing¶

typing.Literal 的行为被改为�循 PEP 586 并匹�该 PEP 所�述的��类型检查器的行为。

  1. Literal 现在将是去��的形�。

  2. Literal 对象间的相等性比较现在将是顺�无关的。

  3. Literal 比较现在会考虑类型。 例如 Literal[0] == Literal[False] 之�的结果值为 True。 现在则为 False。 为支�此改�,内部使用的类型缓存现在也支�区分类型。

  4. 现在如果有任何一个�数�为 hashable,Literal 对象将在相等性比较期间引� TypeError。 请注�使用���数声明 Literal 将�会抛出异常:

    >>> from typing import Literal
    >>> Literal[{0}]
    >>> Literal[{0}] == Literal[{False}]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'set'
    

(由 Yurii Karabas 在 bpo-42345 中贡献。)

macOS 11.0 (Big Sur) 与 Apple Silicon Mac 支�¶

对于 3.9.1 版�说,Python 现在完全支�在 macOS 11.0 (Big Sur) 和 Apple Silicon Macs (基于 ARM64 架构) 上构建和�行。 现在�供了一个新的通用构建类型 universal2,用于在一组�执行文件上原生支� ARM64 和 Intel 64。 二进制文件现在也�以在当�版本的 macOS 上编译以部署到多�较旧的 macOS 版本上 (已测试 10.9),�时会基于�行时所使用的�作系统版本让�些较新的 OS 功能和选项有�件地�用 ("弱链接") 。

(由 Ronald Oussoren 和 Lawrence D'Anna 在 bpo-41100 中贡献。)

Python 3.9.2 中的���化¶

collections.abc¶

现在 collections.abc.Callable 泛型会将类型形�展平,类似于 typing.Callable 当�所�的那样。 这�味� collections.abc.Callable[[int, str], str] 的 __args__ 将为 (int, str, str);之�则为 ([int, str], str)。 为了�许这个改�,types.GenericAlias 现在�以被�类化,并且在抽� collections.abc.Callable 类型时将返回一个�类。 通过 typing.get_args() 或 __args__ 访问�数的代�需�考虑到这个改�。 对于无效的 collections.abc.Callable �数化形��能会�出 DeprecationWarning,这在 Python 3.9.1 中�能会�默地传递。 这个 DeprecationWarning 将在 Python 3.10 中�为 TypeError。 (由 Ken Jin 在 bpo-42195 中贡献。)

urllib.parse¶

早先的 Python 版本�许使用 ; 和 & 作为 urllib.parse.parse_qs() 和 urllib.parse.parse_qsl() 中 query 形�的分隔键。 出于安全考虑,也为了�循更新的 W3C 推�设置,这已被改为��许�个分隔键,默认为 &。 这一改�还会影� cgi.parse() 和 cgi.parse_multipart() 因为它们在内部使用了�影�的函数。 �了解更多细节,请查看它们�自的文档。 (由 Adam Goldschmidt, Senthil Kumaran 和 Ken Jin 在 bpo-42967 中贡献。)

Python 3.9.3 中的���化¶

新的安全修正将 ftplib.FTP 的行为改�当设置被动数�通�时�信任远程�务器所��的 IPv4 地�。 我们会改为�用 ftp �务器的 IP 地�。 对于需�原先的行为的�常�代�,请在你的 FTP 实例上将 trust_server_pasv_ipv4_address 属性设为 True。 (�� gh-87451。)

Python 3.9.5 中的���化¶

urllib.parse¶

在 URL 中存在�行符或制表符�能会导致��形�的攻击。 根�更新了 RFC 3986 的 WHATWG 规范,urllib.parse 中的解�器将从 URL 中去除 ASCII �行符 \n, \r 和制表符 \t 以防止这�攻击。 移除的字符将由一个新的模�层级�� urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE �控制。 (�� gh-88048。)

3.9.14 中的��安全特性¶

使用�进制以外的底,如 2(二进制)�4�8(八进制)�16(�六进制)�32 以外作为基数在 int 和 str 之间进行转�,如果字符串形�的数字数�超过一个�制,会抛出 ValueError,以��因算法��而导致的潜在拒��务攻击。这是对 CVE-2020-10735 的缓解方案。这个�制�以通过环境���命令行旗标或 sys API 进行�置或�用。�� integer string conversion length limitation 文档。默认�制是字符串形�的 4300 �数字。

3.9.17 中的���化¶

tarfile¶

  • tarfile 中的æ��å�–方法和 shutil.unpack_archive() 都新增了 filter å�‚数以å…�许é™�制å�¯èƒ½ä»¤äººæ„�外或å�±é™©çš„ tar 特性,例如在目标目录之外创建文件。 相关细节å�‚è§� 解压缩过滤器。 在 Python 3.12 中,ä¸�带 filter å�‚数的用法将显示 DeprecationWarning。 在 Python 3.14 中,默认值将切æ�¢ä¸º 'data'。 (由 Petr Viktorin 在 PEP 706 中贡献。)