Python 3.11 中的新特性¶
- 编辑:
Pablo Galindo Salgado
本文解释了 Python 3.11 相较于 3.10 的新特性。Python 3.11 于 2022 年 10 月 24 日发布。有关完整详细信息,请参阅更新日志。
摘要 – 版本亮点¶
Python 3.11 比 Python 3.10 快 10-60%。平均而言,我们在标准基准测试套件上测量了 1.25 倍的加速。有关详细信息,请参阅更快的 CPython。
新的语法特性
新的内置特性
新的标准库模块
解释器改进
新的
-P
命令行选项和PYTHONSAFEPATH
环境变量,用于禁用自动预先添加可能不安全的路径到sys.path
新的类型特性
重要的弃用、移除和限制
PEP 594:许多旧的标准库模块已被弃用,并将在 Python 3.13 中删除
新特性¶
PEP 657:回溯中的精细错误位置¶
在打印回溯时,解释器现在将指向导致错误的精确表达式,而不仅仅是行。例如
Traceback (most recent call last):
File "distance.py", line 11, in <module>
print(manhattan_distance(p1, p2))
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "distance.py", line 6, in manhattan_distance
return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'
以前版本的解释器只会指向行,使其不明确哪个对象为 None
。当处理深度嵌套的 dict
对象和多个函数调用时,这些增强的错误也很有帮助
Traceback (most recent call last):
File "query.py", line 37, in <module>
magic_arithmetic('foo')
File "query.py", line 18, in magic_arithmetic
return add_counts(x) / 25
^^^^^^^^^^^^^
File "query.py", line 24, in add_counts
return 25 + query_user(user1) + query_user(user2)
^^^^^^^^^^^^^^^^^
File "query.py", line 32, in query_user
return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
~~~~~~~~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable
以及复杂的算术表达式
Traceback (most recent call last):
File "calculation.py", line 54, in <module>
result = (x / y / z) * (a / b / c)
~~~~~~^~~
ZeroDivisionError: division by zero
此外,增强的回溯功能使用的信息可通过通用 API 获得,该 API 可用于将字节码 指令与源代码位置相关联。可以使用以下方法检索此信息
Python 中的
codeobject.co_positions()
方法。C API 中的
PyCode_Addr2Location()
函数。
有关详细信息,请参阅PEP 657。(由 Pablo Galindo、Batuhan Taskaya 和 Ammar Askar 在 bpo-43950 中贡献。)
注意
此功能需要在代码对象中存储列位置,这可能会导致解释器内存使用量和已编译 Python 文件的磁盘使用量略有增加。要避免存储额外信息并停用打印额外回溯信息,请使用 -X no_debug_ranges
命令行选项或 PYTHONNODEBUGRANGES
环境变量。
PEP 654:异常组和 except*
¶
PEP 654 引入了语言特性,使程序能够同时引发和处理多个不相关的异常。内置类型 ExceptionGroup
和 BaseExceptionGroup
使分组异常并将其一起引发成为可能,新的 except*
语法概括了 except
以匹配异常组的子组。
有关详细信息,请参阅PEP 654。
(由 Irit Katriel 在 bpo-45292 中贡献。PEP 由 Irit Katriel、Yury Selivanov 和 Guido van Rossum 撰写。)
PEP 678:可以使用注释来丰富异常¶
add_note()
方法被添加到 BaseException
。它可用于使用在引发异常时不可用的上下文信息来丰富异常。添加的注释将出现在默认的回溯中。
有关详细信息,请参阅PEP 678。
(由 Irit Katriel 在 bpo-45607 中贡献。PEP 由 Zac Hatfield-Dodds 撰写。)
Windows py.exe
启动器改进¶
Python 3.11 中包含的 Windows 版 Python 启动器的副本已得到显著更新。它现在支持 PEP 514 中定义的公司/标签语法,使用 -V:<公司>/<标签>
参数而不是有限的 -<主版本>.<次版本>
。这允许启动 PythonCore
(托管在 python.org 上的)以外的发行版。
当使用 -V:
选择器时,公司或标签可以省略,但会搜索所有安装。例如,-V:OtherPython/
将选择为 OtherPython
注册的“最佳”标签,而 -V:3.11
或 -V:/3.11
将选择带有标签 3.11
的“最佳”发行版。
当使用旧的 -<major>
、 -<major>.<minor>
、 -<major>-<bitness>
或 -<major>.<minor>-<bitness>
参数时,应保留过去版本的所有现有行为,并且仅选择来自 PythonCore
的发行版。但是,-64
后缀现在表示“不是 32 位”(不一定是 x86-64),因为有多个支持的 64 位平台。通过检查运行时的标签是否有 -32
后缀来检测 32 位运行时。自 3.5 以来的所有 Python 版本都在其 32 位构建中包含了此后缀。
其他语言变更¶
现在允许在 异步函数 的推导式内部使用异步 推导式。在这种情况下,外部推导式会隐式变为异步。(由 Serhiy Storchaka 在 bpo-33346 中贡献。)
现在,对于不支持上下文管理器协议的对象,在
with
语句和contextlib.ExitStack.enter_context()
中,将引发TypeError
,而不是AttributeError
。同样地,对于不支持异步上下文管理器协议的对象,在async with
语句和contextlib.AsyncExitStack.enter_async_context()
中,也会引发TypeError
。(由 Serhiy Storchaka 在 bpo-12022 和 bpo-44471 中贡献。)添加了
object.__getstate__()
,它提供了__getstate__()
方法的默认实现。现在,复制和pickle
内置类型bytearray
、set
、frozenset
、collections.OrderedDict
、collections.deque
、weakref.WeakSet
和datetime.tzinfo
的子类的实例时,会复制和 pickle 作为 slots 实现的实例属性。此更改有一个意想不到的副作用:它会使一小部分不希望object.__getstate__()
存在的现有 Python 项目崩溃。有关此类代码可能需要哪些解决方法,请参阅稍后在 gh-70766 上的评论。(由 Serhiy Storchaka 在 bpo-26579 中贡献。)
添加了一个
-P
命令行选项和一个PYTHONSAFEPATH
环境变量,它们在运行脚本时禁用自动将脚本目录前置到sys.path
,或者在使用-c
和-m
时禁用自动将当前目录前置到sys.path
。这确保只有 stdlib 和已安装的模块被import
拾取,并避免无意或恶意地使用本地(通常是用户可写的)目录中的模块来覆盖模块。(由 Victor Stinner 在 gh-57684 中贡献。)在 格式规范迷你语言 中添加了一个
"z"
选项,该选项在舍入到格式精度后将负数强制转换为正零。有关更多详细信息,请参阅 PEP 682。(由 John Belmonte 在 gh-90153 中贡献。)不再接受
sys.path
上的字节。支持在 Python 3.2 和 3.6 之间的某个时间点中断,直到 Python 3.10.0 发布后才有人注意到。此外,由于当存在str
和bytes
键混合时,-b
和sys.path_importer_cache
之间的交互,恢复支持会很麻烦。(由 Thomas Grainger 在 gh-91181 中贡献。)
其他 CPython 实现更改¶
实现了
complex
的特殊方法__complex__()
和bytes
的特殊方法__bytes__()
,以支持typing.SupportsComplex
和typing.SupportsBytes
协议。(由 Mark Dickinson 和 Donghee Na 在 bpo-24234 中贡献。)添加了
siphash13
作为新的内部哈希算法。它具有与siphash24
相似的安全属性,但对于长输入来说速度稍快。str
、bytes
和一些其他类型现在使用它作为hash()
的默认算法。PEP 552 基于哈希值的 .pyc 文件 现在也使用siphash13
。(由 Inada Naoki 在 bpo-29410 中贡献。)当使用不带参数的
raise
语句重新引发活动异常时,附加到此异常的回溯现在始终为sys.exc_info()[1].__traceback__
。这意味着在当前的except
子句中对回溯所做的更改将反映在重新引发的异常中。(由 Irit Katriel 在 bpo-45711 中贡献。)解释器状态对已处理异常的表示(又名
exc_info
或_PyErr_StackItem
)现在只有exc_value
字段;exc_type
和exc_traceback
已被删除,因为它们可以从exc_value
推导出来。(由 Irit Katriel 在 bpo-45711 中贡献。)为 Windows 安装程序添加了一个新的 命令行选项,
AppendPath
。它的行为与PrependPath
类似,但它是追加而不是前置安装目录和脚本目录。(由 Bastian Neuburger 在 bpo-44934 中贡献。)现在必须将
PyConfig.module_search_paths_set
字段设置为1
,以便初始化使用PyConfig.module_search_paths
来初始化sys.path
。否则,初始化将重新计算路径并替换添加到module_search_paths
的任何值。现在,
--help
选项的输出符合 50 行/80 列。关于 Python 环境变量 和-X
选项的信息现在可以使用相应的--help-env
和--help-xoptions
标志获得,并且可以使用新的--help-all
标志获得。(由 Éric Araujo 在 bpo-46142 中贡献。)在 2(二进制)、4、8(八进制)、16(十六进制)或 32 之外的进制中,将
int
和str
之间进行转换时,如果字符串形式的数字位数超过限制,现在会引发ValueError
,以避免由于算法复杂度而导致的潜在拒绝服务攻击。这是对 CVE 2020-10735 的缓解措施。此限制可以通过环境变量、命令行标志或sys
API 进行配置或禁用。请参阅 整数字符串转换长度限制 文档。字符串形式的默认限制是 4300 位数字。
新模块¶
改进的模块¶
asyncio¶
添加了
TaskGroup
类,这是一个异步上下文管理器,持有 一组任务,这些任务在退出时将等待所有任务完成。对于新代码,建议使用此方法而不是直接使用create_task()
和gather()
。(由 Yury Selivanov 等人在 gh-90908 中贡献。)添加了
timeout()
,一个用于为异步操作设置超时的异步上下文管理器。 对于新代码,建议使用此方法而不是直接使用wait_for()
。(由 Andrew Svetlov 在 gh-90927 中贡献。)添加了
Runner
类,该类公开了run()
使用的机制。(由 Andrew Svetlov 在 gh-91218 中贡献。)在 asyncio 库的同步原语中添加了
Barrier
类,以及相关的BrokenBarrierError
异常。(由 Yves Duprat 和 Andrew Svetlov 在 gh-87518 中贡献。)向
asyncio.loop.create_connection()
添加了关键字参数 *all_errors*,以便可以将多个连接错误作为ExceptionGroup
引发。添加了
asyncio.StreamWriter.start_tls()
方法,用于将现有的基于流的连接升级到 TLS。(由 Ian Good 在 bpo-34975 中贡献。)向事件循环添加了原始数据报套接字函数:
sock_sendto()
、sock_recvfrom()
和sock_recvfrom_into()
。这些在SelectorEventLoop
和ProactorEventLoop
中都有实现。(由 Alex Grönholm 在 bpo-46805 中贡献。)向
Task
添加了cancelling()
和uncancel()
方法。这些主要用于内部,特别是被TaskGroup
使用。
contextlib¶
dataclasses¶
datetime¶
添加
datetime.UTC
,它是datetime.timezone.utc
的便捷别名。(由 Kabir Kwatra 在 gh-91973 中贡献。)datetime.date.fromisoformat()
、datetime.time.fromisoformat()
和datetime.datetime.fromisoformat()
现在可用于解析大多数 ISO 8601 格式(仅排除那些支持小数小时和分钟的格式)。(由 Paul Ganssle 在 gh-80010 中贡献。)
enum¶
将
EnumMeta
重命名为EnumType
(保留EnumMeta
作为别名)。添加了
StrEnum
,其成员可以用作(并且必须是)字符串。添加了
ReprEnum
,它只修改成员的__repr__()
,同时为其__str__()
和__format__()
(由str()
、format()
和 f-string 使用)返回其字面量值(而不是名称)。更改了
Enum.__format__()
(format()
、str.format()
和 f-string 的默认值),使其始终产生与Enum.__str__()
相同的结果:对于继承自ReprEnum
的枚举,它将是成员的值;对于所有其他枚举,它将是枚举和成员名称(例如,Color.RED
)。为
Flag
枚举和FlagBoundary
枚举及其选项添加了一个新的 boundary 类参数,用于控制如何处理超出范围的标志值。添加了
member()
和nonmember()
装饰器,以确保被装饰的对象被/不被转换为枚举成员。添加了
property()
装饰器,它的工作方式类似于property()
,但用于枚举。请使用它来代替types.DynamicClassAttribute()
。添加了
global_enum()
枚举装饰器,它会调整__repr__()
和__str__()
以将值显示为它们模块的成员,而不是枚举类的成员。例如,对于re.RegexFlag
的ASCII
成员,显示're.ASCII'
而不是'RegexFlag.ASCII'
。增强了
Flag
,使其支持在其成员上使用len()
、迭代以及in
/not in
。例如,现在以下代码可以正常工作:len(AFlag(3)) == 2 and list(AFlag(3)) == (AFlag.ONE, AFlag.TWO)
更改了
Enum
和Flag
,以便成员现在在调用__init_subclass__()
之前定义;dir()
现在包括来自混合数据类型的方法等。更改了
Flag
,使其仅将主值(2 的幂)视为规范值,而将复合值(3
、6
、10
等)视为别名;反转标志被强制转换为其正等效值。
fcntl¶
在 FreeBSD 上,支持
F_DUP2FD
和F_DUP2FD_CLOEXEC
标志,前者等于dup2
的用法,而后者则额外设置了FD_CLOEXEC
标志。
fractions¶
functools¶
functools.singledispatch()
现在支持将types.UnionType
和typing.Union
作为调度参数的注释。>>> from functools import singledispatch >>> @singledispatch ... def fun(arg, verbose=False): ... if verbose: ... print("Let me just say,", end=" ") ... print(arg) ... >>> @fun.register ... def _(arg: int | float, verbose=False): ... if verbose: ... print("Strength in numbers, eh?", end=" ") ... print(arg) ... >>> from typing import Union >>> @fun.register ... def _(arg: Union[list, set], verbose=False): ... if verbose: ... print("Enumerate this:") ... for i, elem in enumerate(arg): ... print(i, elem) ...
(由 Yurii Karabas 在 bpo-46014 中贡献。)
gzip¶
当使用 mtime=0 参数时,
gzip.compress()
函数现在更快,因为它将压缩完全委托给单个zlib.compress()
操作。此更改有一个副作用:gzip 文件头在其头部包含一个“OS”字节。传统上,gzip
模块始终将其设置为值 255,表示“未知”。现在,当使用 mtime=0 的compress()
时,它可能会被 Python 链接到的底层 zlib C 库设置为不同的值。(有关副作用的详细信息,请参阅 gh-112346。)
hashlib¶
hashlib.blake2b()
和hashlib.blake2s()
现在首选 libb2 而不是 Python 的供应商副本。(由 Christian Heimes 在 bpo-47095 中贡献。)带有 SHA3 和 SHAKE 算法的内部
_sha3
模块现在使用 tiny_sha3 而不是 Keccak Code Package 来减少代码和二进制大小。hashlib
模块首选来自 OpenSSL 的优化 SHA3 和 SHAKE 实现。此更改仅影响没有 OpenSSL 支持的安装。(由 Christian Heimes 在 bpo-47098 中贡献。)添加了
hashlib.file_digest()
,这是一个用于有效哈希文件或类文件对象的辅助函数。(由 Christian Heimes 在 gh-89313 中贡献。)
IDLE 和 idlelib¶
inspect¶
添加
getmembers_static()
以返回所有成员,而不触发通过描述符协议的动态查找。(由 Weipeng Hong 在 bpo-30533 中贡献。)添加
ismethodwrapper()
以检查对象的类型是否为MethodWrapperType
。(由 Hakan Çelik 在 bpo-29418 中贡献。)更改
inspect
模块中与帧相关的函数,使其返回新的FrameInfo
和Traceback
类实例(与之前的类似 命名元组 的接口向后兼容),其中包含扩展的 PEP 657 位置信息(结束行号、列和结束列)。受影响的函数有:(由 Pablo Galindo 在 gh-88116 中贡献。)
locale¶
添加
locale.getencoding()
以获取当前区域设置编码。它类似于locale.getpreferredencoding(False)
,但忽略 Python UTF-8 模式。
logging¶
添加了
getLevelNamesMapping()
,用于返回从日志级别名称(例如'CRITICAL'
)到其对应的日志级别值(例如,默认情况下为50
)的映射。(由 Andrei Kulakovin 在 gh-88024 中贡献。)为
SysLogHandler
添加了createSocket()
方法,以匹配SocketHandler.createSocket()
。它在处理程序初始化期间和在发出事件时(如果没有活动套接字)自动调用。(由 Kirill Pinchuk 在 gh-88457 中贡献。)
math¶
添加
math.exp2()
:返回 2 的 x 次幂。(由 Gideon Mitchell 在 bpo-45917 中贡献。)添加
math.cbrt()
:返回 x 的立方根。(由 Ajith Ramachandran 在 bpo-44357 中贡献。)为了与 IEEE 754 规范保持一致,更改了
math.pow()
的两个极端情况的行为。math.pow(0.0, -math.inf)
和math.pow(-0.0, -math.inf)
操作现在返回inf
。以前它们会引发ValueError
。(由 Mark Dickinson 在 bpo-44339 中贡献。)
operator¶
添加了一个新函数
operator.call
,使得operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)
。(由 Antony Lee 在 bpo-44019 中贡献。)
os¶
在 Windows 上,
os.urandom()
现在使用BCryptGenRandom()
,而不是已弃用的CryptGenRandom()
。(由 Donghee Na 在 bpo-44611 中贡献。)
pathlib¶
re¶
正则表达式现在支持原子分组 (
(?>...)
) 和占有量词 (*+
、++
、?+
、{m,n}+
)。(由 Jeffrey C. Jacobs 和 Serhiy Storchaka 在 bpo-433030 中贡献。)
shutil¶
在
shutil.rmtree()
中添加可选参数 *dir_fd*。(由 Serhiy Storchaka 在 bpo-46245 中贡献。)
socket¶
为 NetBSD 添加 CAN 套接字支持。(由 Thomas Klausner 在 bpo-30512 中贡献。)
如果连接失败,
create_connection()
有一个选项可以引发一个包含所有错误的ExceptionGroup
,而不是只引发最后一个错误。(由 Irit Katriel 在 bpo-29980 中贡献。)
sqlite3¶
现在可以通过将
None
传递给set_authorizer()
来禁用授权器。(由 Erlend E. Aasland 在 bpo-44491 中贡献。)create_collation()
的排序规则名称现在可以包含任何 Unicode 字符。具有无效字符的排序规则名称现在会引发UnicodeEncodeError
,而不是sqlite3.ProgrammingError
。(由 Erlend E. Aasland 在 bpo-44688 中贡献。)sqlite3
异常现在包含 SQLite 扩展错误代码(作为sqlite_errorcode
)和 SQLite 错误名称(作为sqlite_errorname
)。(由 Aviv Palivoda、Daniel Shahaf 和 Erlend E. Aasland 在 bpo-16379 和 bpo-24139 中贡献。)为
sqlite3.Connection
添加setlimit()
和getlimit()
,用于按连接设置和获取 SQLite 限制。(由 Erlend E. Aasland 在 bpo-45243 中贡献。)sqlite3
现在基于底层 SQLite 库编译时使用的默认线程模式设置sqlite3.threadsafety
。(由 Erlend E. Aasland 在 bpo-45613 中贡献。)如果启用了回调回溯,
sqlite3
C 回调现在使用不可引发的异常。用户现在可以注册一个不可引发的钩子处理程序
来改善他们的调试体验。(由 Erlend E. Aasland 在 bpo-45828 中贡献。)在回滚期间执行提取操作不再引发
InterfaceError
异常。相反,我们将其留给 SQLite 库来处理这些情况。(由 Erlend E. Aasland 在 bpo-44092 中贡献。)为
sqlite3.Connection
添加serialize()
和deserialize()
方法,用于序列化和反序列化数据库。(由 Erlend E. Aasland 在 bpo-41930 中贡献。)为
sqlite3.Connection
添加create_window_function()
方法,用于创建聚合窗口函数。(由 Erlend E. Aasland 在 bpo-34916 中贡献。)为
sqlite3.Connection
添加blobopen()
方法。sqlite3.Blob
允许对 blob 执行增量 I/O 操作。(由 Aviv Palivoda 和 Erlend E. Aasland 在 bpo-24905 中贡献。)
string¶
为
string.Template
添加get_identifiers()
和is_valid()
方法,它们分别返回所有有效的占位符,以及是否存在任何无效的占位符。(由 Ben Kehoe 在 gh-90465 中贡献。)
sys¶
sys.exc_info()
现在从value
(异常实例) 中派生出type
和traceback
字段,因此当异常在处理过程中被修改时,对exc_info()
的后续调用结果会反映这些更改。(由 Irit Katriel 在 bpo-45711 中贡献。)添加
sys.exception()
,它返回当前活动的异常实例(等效于sys.exc_info()[1]
)。(由 Irit Katriel 在 bpo-46328 中贡献。)添加
sys.flags.safe_path
标志。(由 Victor Stinner 在 gh-57684 中贡献。)
sysconfig¶
添加了三种新的 安装方案(posix_venv、nt_venv 和 venv),当 Python 创建新的虚拟环境或从虚拟环境中运行时使用。前两种方案(posix_venv 和 nt_venv)是特定于操作系统的,分别用于非 Windows 和 Windows,venv 本质上是根据 Python 运行的操作系统对其中一种方案的别名。这对于修改
sysconfig.get_preferred_scheme()
的下游发行商很有用。创建新虚拟环境的第三方代码应使用新的 venv 安装方案来确定路径,就像venv
一样。(由 Miro Hrončok 在 bpo-45413 中贡献。)
tempfile¶
SpooledTemporaryFile
对象现在完全实现了io.BufferedIOBase
或io.TextIOBase
的方法(取决于文件模式)。这使得它们可以与期望类文件对象的 API(如压缩模块)正常工作。(由 Carey Metcalfe 在 gh-70363 中贡献。)
threading¶
在 Unix 上,如果 C 库中提供了
sem_clockwait()
函数(glibc 2.30 及更高版本),则threading.Lock.acquire()
方法现在使用单调时钟(time.CLOCK_MONOTONIC
)进行超时,而不是使用系统时钟(time.CLOCK_REALTIME
),以避免受系统时钟更改的影响。(由 Victor Stinner 在 bpo-41710 中贡献。)
time¶
在 Unix 上,
time.sleep()
现在使用clock_nanosleep()
或nanosleep()
函数(如果可用),其分辨率为 1 纳秒(10-9 秒),而不是使用分辨率为 1 微秒(10-6 秒)的select()
。(由 Benjamin Szőke 和 Victor Stinner 在 bpo-21302 中贡献。)在 Windows 8.1 及更高版本上,
time.sleep()
现在使用基于 高分辨率定时器的可等待计时器,其分辨率为 100 纳秒(10-7 秒)。以前,它的分辨率为 1 毫秒(10-3 秒)。(由 Benjamin Szőke、Donghee Na、Eryk Sun 和 Victor Stinner 在 bpo-21302 和 bpo-45429 中贡献。)
tkinter¶
添加了方法
info_patchlevel()
,它返回 Tcl 库的精确版本,作为一个类似于sys.version_info
的命名元组。(由 Serhiy Storchaka 在 gh-91827 中贡献。)
traceback¶
添加
traceback.StackSummary.format_frame_summary()
,允许用户覆盖哪些帧出现在回溯中以及如何格式化它们。(由 Ammar Askar 在 bpo-44569 中贡献。)添加
traceback.TracebackException.print()
,它将格式化的TracebackException
实例打印到文件中。(由 Irit Katriel 在 bpo-33809 中贡献。)
typing¶
有关重大更改,请参阅 与类型提示相关的新功能。
添加
typing.assert_never()
和typing.Never
。typing.assert_never()
对于要求类型检查器确认一行代码不可访问很有用。在运行时,它会引发AssertionError
。(由 Jelle Zijlstra 在 gh-90633 中贡献。)添加
typing.reveal_type()
。这对于询问类型检查器它为给定的表达式推断了什么类型很有用。在运行时,它会打印接收到的值的类型。(由 Jelle Zijlstra 在 gh-90572 中贡献。)添加了
typing.assert_type()
。 此方法用于要求类型检查器确认其推断出的给定表达式的类型与给定的类型是否匹配。在运行时,它只返回接收到的值。(由 Jelle Zijlstra 在 gh-90638 中贡献。)typing.TypedDict
类型现在可以是泛型的。(由 Samodya Abeysiriwardane 在 gh-89026 中贡献。)NamedTuple
类型现在可以是泛型的。(由 Serhiy Storchaka 在 bpo-43923 中贡献。)允许
typing.Any
的子类化。 这有助于避免与高度动态的类(例如 mocks)相关的类型检查器错误。(由 Shantanu Jain 在 gh-91154 中贡献。)typing.final()
装饰器现在在被装饰的对象上设置__final__
属性。(由 Jelle Zijlstra 在 gh-90500 中贡献。)typing.get_overloads()
函数可用于内省函数的重载。typing.clear_overloads()
可用于清除函数的所有已注册重载。(由 Jelle Zijlstra 在 gh-89263 中贡献。)__init__()
方法现在保留Protocol
子类。(由 Adrian Garcia Badarasco 在 gh-88970 中贡献。)空元组类型(
Tuple[()]
)的表示形式已简化。 这会影响内省,例如,get_args(Tuple[()])
现在求值为()
而不是((),)
。(由 Serhiy Storchaka 在 gh-91137 中贡献。)通过删除私有
typing._type_check
函数中的可调用检查,放宽了类型注释的运行时要求。(由 Gregory Beauregard 在 gh-90802 中贡献。)typing.get_type_hints()
现在支持在 PEP 585 泛型别名 中将字符串评估为前向引用。(由 Niklas Rosenstein 在 gh-85542 中贡献。)typing.get_type_hints()
不再将Optional
添加到默认值为None
的参数。(由 Nikita Sobolev 在 gh-90353 中贡献。)typing.get_type_hints()
现在支持评估裸字符串化的ClassVar
注释。(由 Gregory Beauregard 在 gh-90711 中贡献。)typing.no_type_check()
不再修改外部类和函数。 它现在还正确地将 classmethod 标记为不进行类型检查。(由 Nikita Sobolev 在 gh-90729 中贡献。)
unicodedata¶
Unicode 数据库已更新至 14.0.0 版本。(由 Benjamin Peterson 在 bpo-45190 中贡献。)
unittest¶
添加了类
TestCase
的方法enterContext()
和enterClassContext()
,类IsolatedAsyncioTestCase
的方法enterAsyncContext()
,以及函数unittest.enterModuleContext()
。(由 Serhiy Storchaka 在 bpo-45046 中贡献。)
venv¶
创建新的 Python 虚拟环境时,venv sysconfig 安装方案 用于确定环境内的路径。 当 Python 在虚拟环境中运行时,相同的安装方案是默认方案。 这意味着下游分发商可以更改默认的 sysconfig 安装方案,而无需更改虚拟环境的行为。 创建新虚拟环境的第三方代码也应执行相同的操作。(由 Miro Hrončok 在 bpo-45413 中贡献。)
warnings¶
warnings.catch_warnings()
现在接受warnings.simplefilter()
的参数,从而提供了一种更简洁的方式来局部忽略警告或将其转换为错误。(由 Zac Hatfield-Dodds 在 bpo-47074 中贡献。)
zipfile¶
添加了对指定成员名称编码的支持,用于在
ZipFile
的目录和文件标头中读取元数据。(由 Stephen J. Turnbull 和 Serhiy Storchaka 在 bpo-28080 中贡献。)添加了
ZipFile.mkdir()
,用于在 ZIP 存档中创建新目录。(由 Sam Ezeh 在 gh-49083 中贡献。)为
zipfile.Path
添加了stem
、suffix
和suffixes
。(由 Miguel Brito 在 gh-88261 中贡献。)
优化¶
本节介绍独立于 Faster CPython 项目的特定优化,该项目将在其自己的部分中介绍。
编译器现在优化仅包含格式代码
%s
、%r
和%a
的字符串字面量上的简单 printf 样式 % 格式化,并使其与相应的 f-string 表达式一样快。(由 Serhiy Storchaka 在 bpo-28307 中贡献。)整数除法(
//
)更适合编译器进行优化。当使用小于2**30
的值去除一个int
时,在 x86-64 架构上速度现在提升了约 20%。(由 Gregory P. Smith 和 Tim Peters 在 gh-90564 中贡献。)sum()
函数现在对于小于2**30
的整数快了近 30%。(由 Stefan Behnel 在 gh-68264 中贡献。)列表调整大小针对常见情况进行了优化,使
list.append()
的速度提高了约 15%,简单的列表推导式的速度提高了 20-30% (由 Dennis Sweeney 在 gh-91165 中贡献。)当所有键都是 Unicode 对象时,字典不再存储哈希值,从而减小了
dict
的大小。例如,在 64 位平台上,sys.getsizeof(dict.fromkeys("abcdefg"))
从 352 字节减少到 272 字节(缩小了 23%)。(由 Inada Naoki 在 bpo-46845 中贡献。)当通过 UDP 传输大文件时,使用
asyncio.DatagramProtocol
的速度现在提升了几个数量级,对于大约 60 MiB 的文件,速度提高了 100 倍以上。(由 msoxzw 在 gh-91487 中贡献。)math
模块中的comb()
和perm()
函数对于大参数的速度现在快了约 10 倍(对于较大的 k,加速效果更明显)。(由 Serhiy Storchaka 在 bpo-37295 中贡献。)statistics
模块中的mean()
、variance()
和stdev()
函数现在以一次遍历的方式处理迭代器,而不是先将其转换为list
。 这速度快了两倍,并且可以节省大量内存。(由 Raymond Hettinger 在 gh-90415 中贡献。)unicodedata.normalize()
现在可以在恒定时间内规范化纯 ASCII 字符串。(由 Donghee Na 在 bpo-44987 中贡献。)
更快的 CPython¶
使用 Ubuntu Linux 上的 GCC 编译时,CPython 3.11 比 CPython 3.10 平均快 25%,这是通过 pyperformance 基准测试套件测量的。 根据您的工作负载,整体加速可能在 10-60% 之间。
此项目侧重于 Python 中的两个主要领域:更快的启动 和 更快的运行时。 此项目未涵盖的优化单独列在 优化 下。
更快的启动¶
冻结导入/静态代码对象¶
Python 在 __pycache__ 目录中缓存字节码,以加快模块加载速度。
在之前的 3.10 版本中,Python 模块执行如下所示
Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate
在 Python 3.11 中,Python 启动所必需的核心模块是“冻结的”。 这意味着它们的 代码对象(和字节码)由解释器静态分配。 这将模块执行过程中的步骤减少为
Statically allocated code object -> Evaluate
Python 3.11 中解释器启动速度现在快了 10-15%。 这对于使用 Python 的短时间运行程序有很大的影响。
(由 Eric Snow、Guido van Rossum 和 Kumar Aditya 在许多问题中贡献。)
更快的运行时¶
更便宜、延迟的 Python 帧¶
每当 Python 调用 Python 函数时,都会创建保存执行信息的 Python 帧。 以下是新的帧优化
简化了帧创建过程。
通过在 C 堆栈上大量重用帧空间来避免内存分配。
简化了内部帧结构,使其仅包含必要的信息。 帧以前包含额外的调试和内存管理信息。
只有当调试器或 Python 内省函数(如 sys._getframe()
和 inspect.currentframe()
)请求时,才会创建旧式帧对象。 对于大多数用户代码,根本不会创建帧对象。 因此,几乎所有 Python 函数调用都得到了显著加速。 我们在 pyperformance 中测量到了 3-7% 的加速。
(由 Mark Shannon 在 bpo-44590 中贡献。)
内联 Python 函数调用¶
在 Python 函数调用期间,Python 将调用一个评估 C 函数来解释该函数的代码。 这实际上将纯 Python 递归限制为 C 堆栈安全范围内的递归。
在 3.11 中,当 CPython 检测到 Python 代码调用另一个 Python 函数时,它会设置一个新帧,并“跳转”到新帧内的新代码。 这避免了完全调用 C 解释函数。
现在,大多数 Python 函数调用都不占用 C 堆栈空间,从而加快了速度。 在像 fibonacci 或阶乘这样的简单递归函数中,我们观察到了 1.7 倍的加速。 这也意味着递归函数可以递归得更深(如果用户使用 sys.setrecursionlimit()
增加递归限制)。 我们在 pyperformance 中测量到了 1-3% 的改进。
(由 Pablo Galindo 和 Mark Shannon 在 bpo-45256 中贡献。)
PEP 659:专门化的自适应解释器¶
PEP 659 是 Faster CPython 项目的关键组成部分之一。 其总体思想是,虽然 Python 是一种动态语言,但大多数代码都存在对象和类型很少更改的区域。 此概念称为类型稳定性。
在运行时,Python 将尝试查找正在执行的代码中的常见模式和类型稳定性。 然后,Python 会将当前操作替换为更专门化的操作。 这种专门化的操作使用仅适用于这些用例/类型的快速路径,通常其性能优于通用操作。 这也引入了另一个称为内联缓存的概念,其中 Python 直接在 字节码中缓存开销较大的操作的结果。
特殊化程序还将某些常见的指令对组合成一个超级指令,从而减少执行期间的开销。
Python 仅在看到“热”(多次执行)的代码时才进行特殊化。 这可以防止 Python 在只运行一次的代码上浪费时间。 当代码过于动态或使用方式发生变化时,Python 也可以取消特殊化。 会定期尝试特殊化,并且特殊化尝试的开销并不太大,从而允许特殊化适应新的情况。
(PEP 由 Mark Shannon 编写,其思想受到 Stefan Brunthaler 的启发。 请参阅PEP 659 获取更多信息。 由 Mark Shannon 和 Brandt Bucher 实现,并得到了 Irit Katriel 和 Dennis Sweeney 的额外帮助。)
操作 |
形式 |
特殊化 |
操作加速(高达) |
贡献者 |
---|---|---|---|---|
二元运算 |
|
10% |
Mark Shannon、Donghee Na、Brandt Bucher、Dennis Sweeney |
|
下标 |
|
对诸如 自定义的 |
10-25% |
Irit Katriel, Mark Shannon |
存储下标 |
|
类似于上面的下标操作特化。 |
10-25% |
Dennis Sweeney |
调用 |
|
对诸如 |
20% |
Mark Shannon, Ken Jin |
加载全局变量 |
|
对象在全局/内置命名空间中的索引会被缓存。加载全局变量和内置变量无需进行命名空间查找。 |
Mark Shannon |
|
加载属性 |
|
类似于加载全局变量。属性在类/对象命名空间中的索引会被缓存。在大多数情况下,加载属性将不需要进行命名空间查找。 |
Mark Shannon |
|
加载用于调用的方法 |
|
方法的实际地址会被缓存。现在加载方法无需进行命名空间查找,即使对于具有很长继承链的类也是如此。 |
10-20% |
Ken Jin, Mark Shannon |
存储属性 |
|
类似于加载属性的优化。 |
在 pyperformance 中占 2% |
Mark Shannon |
解包序列 |
|
8% |
Brandt Bucher |
其他¶
由于延迟创建的对象命名空间,现在对象需要的内存更少。它们的命名空间字典现在也可以更自由地共享键。(由 Mark Shannon 在 bpo-45340 和 bpo-40116 中贡献。)
实现了“零成本”异常,消除了在未引发异常时
try
语句的开销。(由 Mark Shannon 在 bpo-40222 中贡献。)解释器中更简洁的异常表示形式将捕获异常所需的时间减少了约 10%。(由 Irit Katriel 在 bpo-45711 中贡献。)
re
的正则表达式匹配引擎已被部分重构,现在在支持的平台上使用计算的 goto(或“线程代码”)。因此,Python 3.11 执行 pyperformance 正则表达式基准测试的速度比 Python 3.10 快 10%。 (由 Brandt Bucher 在 gh-91404 中贡献。)
常见问题解答¶
我应该如何编写代码来利用这些加速?¶
编写遵循常见最佳实践的 Pythonic 代码;你无需更改代码。Faster CPython 项目针对我们观察到的常见代码模式进行优化。
CPython 3.11 会使用更多内存吗?¶
可能不会;我们预计内存使用量不会比 3.10 高出 20%。这可以通过上述针对帧对象和对象字典的内存优化来抵消。
我没有在我的工作负载中看到任何加速。为什么?¶
某些代码不会有明显的收益。如果你的代码大部分时间都花在 I/O 操作上,或者已经在像 NumPy 这样的 C 扩展库中完成了大部分计算,那么就不会有显著的加速。此项目目前对纯 Python 工作负载的收益最大。
此外,pyperformance 数据是几何平均值。即使在 pyperformance 基准测试中,某些基准测试也略有放缓,而另一些基准测试则加速了近 2 倍!
有 JIT 编译器吗?¶
没有。我们仍在探索其他优化。
关于¶
Faster CPython 探索 CPython 的优化。主要团队由 Microsoft 资助全职从事这项工作。Pablo Galindo Salgado 也由 Bloomberg LP 资助兼职从事该项目。最后,许多贡献者是来自社区的志愿者。
CPython 字节码更改¶
字节码现在包含内联缓存条目,其形式为新添加的 CACHE
指令。许多操作码都期望后跟确切数量的缓存,并指示解释器在运行时跳过它们。填充的缓存看起来可能像任意指令,因此在读取或修改包含加速数据的原始自适应字节码时应格外小心。
新操作码¶
ASYNC_GEN_WRAP
、RETURN_GENERATOR
和SEND
,用于生成器和协程。COPY_FREE_VARS
,避免了对闭包使用特殊的调用方代码。JUMP_BACKWARD_NO_INTERRUPT
,用于某些不希望处理中断的循环。CHECK_EG_MATCH
和PREP_RERAISE_STAR
,用于处理在 PEP 654 中添加的新异常组和 except*。PUSH_EXC_INFO
,用于异常处理程序。RESUME
,一个空操作,用于内部跟踪、调试和优化检查。
替换的操作码¶
替换的操作码 |
新的操作码 |
注释 |
---|---|---|
BINARY_* INPLACE_* |
将所有数值二进制/就地操作码替换为单个操作码 |
|
CALL_FUNCTION CALL_FUNCTION_KW CALL_METHOD |
将方法的参数移位与关键字参数的处理解耦;允许更好地特化调用 |
|
DUP_TOP DUP_TOP_TWO ROT_TWO ROT_THREE ROT_FOUR ROT_N |
堆栈操作指令 |
|
JUMP_IF_NOT_EXC_MATCH |
现在执行检查但不跳转 |
|
JUMP_ABSOLUTE POP_JUMP_IF_FALSE POP_JUMP_IF_TRUE |
请参阅[3];每个方向的 |
|
SETUP_WITH SETUP_ASYNC_WITH |
|
所有跳转操作码现在都是相对的,包括现有的 JUMP_IF_TRUE_OR_POP
和 JUMP_IF_FALSE_OR_POP
。参数现在是相对于当前指令的偏移量,而不是绝对位置。
已更改/删除的操作码¶
更改了
MATCH_CLASS
和MATCH_KEYS
,使其不再推送额外的布尔值来指示成功/失败。相反,如果失败,则会推送None
来代替提取的值的元组。更改了与异常一起使用的操作码,以反映它们现在在堆栈上表示为一个项目,而不是三个(请参阅 gh-89874)。
删除了
COPY_DICT_WITHOUT_KEYS
、GEN_START
、POP_BLOCK
、SETUP_FINALLY
和YIELD_FROM
。
已弃用¶
本节列出了 Python 3.11 中已弃用的 Python API。
已弃用的 C API 将单独列出。
语言/内置函数¶
链式
classmethod
描述符(在 bpo-19072 中引入)现已弃用。它不再能用于包装其他描述符,例如property
。此功能的核心设计存在缺陷,并导致了许多下游问题。要“传递”一个classmethod
,请考虑使用 Python 3.10 中添加的__wrapped__
属性。(由 Raymond Hettinger 在 gh-89519 中贡献。)在字符串和字节字面量中使用大于
0o377
(十进制的 255) 的八进制转义现在会产生一个DeprecationWarning
。在未来的 Python 版本中,它们将引发一个SyntaxWarning
,并最终引发一个SyntaxError
。(由 Serhiy Storchaka 在 gh-81548 中贡献。)现在已弃用将
int()
委托给__trunc__()
。当type(a)
实现__trunc__()
但没有实现__int__()
或__index__()
时调用int(a)
现在会引发一个DeprecationWarning
。(由 Zackery Spytz 在 bpo-44977 中贡献。)
模块¶
PEP 594 导致以下模块被弃用,计划在 Python 3.13 中移除
aifc
chunk
msilib
pipes
telnetlib
audioop
crypt
nis
sndhdr
uu
cgi
imghdr
nntplib
spwd
xdrlib
cgitb
mailcap
ossaudiodev
sunau
(由 Brett Cannon 在 bpo-47061 中贡献,Victor Stinner 在 gh-68966 中贡献。)
asynchat
、asyncore
和smtpd
模块至少自 Python 3.6 以来就被弃用了。它们的文档和弃用警告现在已更新,以说明它们将在 Python 3.12 中移除。(由 Hugo van Kemenade 在 bpo-47022 中贡献。)lib2to3
包和2to3
工具现在已弃用,可能无法解析 Python 3.10 或更高版本。有关详细信息,请参阅引入新 PEG 解析器的 PEP 617。(由 Victor Stinner 在 bpo-40360 中贡献。)未文档化的模块
sre_compile
、sre_constants
和sre_parse
现在已弃用。(由 Serhiy Storchaka 在 bpo-47152 中贡献。)
标准库¶
自 Python 3.2 以来,以下内容在
configparser
中已弃用。它们的弃用警告现在已更新,以说明它们将在 Python 3.12 中移除configparser.SafeConfigParser
类configparser.ParsingError.filename
属性configparser.RawConfigParser.readfp()
方法
(由 Hugo van Kemenade 在 bpo-45173 中贡献。)
configparser.LegacyInterpolation
自 Python 3.2 以来在文档字符串中已弃用,并且未在configparser
文档中列出。它现在会发出一个DeprecationWarning
,并将在 Python 3.13 中移除。请改用configparser.BasicInterpolation
或configparser.ExtendedInterpolation
。(由 Hugo van Kemenade 在 bpo-46607 中贡献。)较旧的一组
importlib.resources
函数已被弃用,取而代之的是在 Python 3.9 中添加的替换函数,并且由于不支持位于包子目录中的资源,将在未来的 Python 版本中移除importlib.resources.contents()
importlib.resources.is_resource()
importlib.resources.open_binary()
importlib.resources.open_text()
importlib.resources.read_binary()
importlib.resources.read_text()
importlib.resources.path()
locale.getdefaultlocale()
函数已弃用,将在 Python 3.15 中移除。请改用locale.setlocale()
、locale.getpreferredencoding(False)
和locale.getlocale()
函数。(由 Victor Stinner 在 gh-90817 中贡献。)locale.resetlocale()
函数已弃用,将在 Python 3.13 中移除。请改用locale.setlocale(locale.LC_ALL, "")
。(由 Victor Stinner 在 gh-90817 中贡献。)现在将对 正则表达式 中的数字组引用和组名称应用更严格的规则。现在,只有 ASCII 数字序列会被接受为数字引用,并且
bytes
模式和替换字符串中的组名称只能包含 ASCII 字母、数字和下划线。现在,对于违反这些规则的语法,会引发弃用警告。(由 Serhiy Storchaka 在 gh-91760 中贡献。)在
re
模块中,re.template()
函数以及相应的re.TEMPLATE
和re.T
标志已弃用,因为它们未文档化且缺乏明确的用途。它们将在 Python 3.13 中移除。(由 Serhiy Storchaka 和 Miro Hrončok 在 gh-92728 中贡献。)turtle.settiltangle()
自 Python 3.1 以来已弃用;它现在会发出弃用警告,并将在 Python 3.13 中移除。请改用turtle.tiltangle()
(它之前被错误地标记为已弃用,并且它的文档字符串现在已更正)。(由 Hugo van Kemenade 在 bpo-45837 中贡献。)typing.Text
仅用于在 Python 2 和 Python 3 代码之间提供兼容性支持,现在已弃用。目前尚未计划将其移除,但鼓励用户尽可能使用str
。(由 Alex Waygood 在 gh-92332 中贡献。)现在已弃用用于构造
typing.TypedDict
类型的关键字参数语法。支持将在 Python 3.13 中移除。(由 Jingchen Ye 在 gh-90224 中贡献。)webbrowser.MacOSX
已弃用,将在 Python 3.13 中移除。它是未经测试的、未文档化的,并且webbrowser
本身不使用它。(由 Donghee Na 在 bpo-42255 中贡献。)现在已弃用从
TestCase
和IsolatedAsyncioTestCase
测试方法返回值(除了默认的None
值)的行为。以下未正式文档化的
unittest
函数已被弃用,计划在 Python 3.13 中移除。unittest.findTestCases()
unittest.makeSuite()
unittest.getTestCaseNames()
请改用
TestLoader
方法。(由 Erlend E. Aasland 在 bpo-5846 中贡献。)
unittest.TestProgram.usageExit()
被标记为已弃用,将在 3.13 中移除。(由 Carlos Damázio 在 gh-67048 中贡献。)
计划在 Python 3.12 中移除¶
以下 Python API 在早期的 Python 版本中已被弃用,并将在 Python 3.12 中移除。
计划移除的 C API 将单独列出。
asynchat
模块asyncore
模块imp
模块typing.io
命名空间typing.re
命名空间cgi.log()
importlib.find_loader()
importlib.abc.Loader.module_repr()
importlib.abc.MetaPathFinder.find_module()
importlib.abc.PathEntryFinder.find_loader()
importlib.abc.PathEntryFinder.find_module()
importlib.machinery.BuiltinImporter.find_module()
importlib.machinery.BuiltinLoader.module_repr()
importlib.machinery.FileFinder.find_loader()
importlib.machinery.FileFinder.find_module()
importlib.machinery.FrozenImporter.find_module()
importlib.machinery.FrozenLoader.module_repr()
importlib.machinery.PathFinder.find_module()
importlib.machinery.WindowsRegistryFinder.find_module()
importlib.util.module_for_loader()
importlib.util.set_loader_wrapper()
importlib.util.set_package_wrapper()
pkgutil.ImpImporter
pkgutil.ImpLoader
pathlib.Path.link_to()
sqlite3.enable_shared_cache()
sqlite3.OptimizedUnicode()
PYTHONTHREADDEBUG
环境变量以下
unittest
中的已弃用别名已弃用别名
方法名称
弃用版本
failUnless
3.1
failIf
3.1
failUnlessEqual
3.1
failIfEqual
3.1
failUnlessAlmostEqual
3.1
failIfAlmostEqual
3.1
failUnlessRaises
3.1
assert_
3.2
assertEquals
3.2
assertNotEquals
3.2
assertAlmostEquals
3.2
assertNotAlmostEquals
3.2
assertRegexpMatches
3.2
assertRaisesRegexp
3.2
assertNotRegexpMatches
3.5
已移除¶
本节列出了在 Python 3.11 中已移除的 Python API。
已移除的 C API 将单独列出。
移除了
@asyncio.coroutine()
装饰器,该装饰器使基于旧式生成器的协程能够与async
/await
代码兼容。 该函数自 Python 3.8 起已弃用,并且最初计划在 Python 3.10 中移除。请改用async def
。(由 Illia Volochii 在 bpo-43216 中贡献。)移除了
asyncio.coroutines.CoroWrapper
,该类用于在调试模式下包装基于旧式生成器的协程对象。(由 Illia Volochii 在 bpo-43216 中贡献。)由于存在重大的安全隐患,
asyncio.loop.create_datagram_endpoint()
的 *reuse_address* 参数已在 Python 3.9 中禁用,现在已完全移除。 这是由于 UDP 中套接字选项SO_REUSEADDR
的行为所致。(由 Hugo van Kemenade 在 bpo-45129 中贡献。)移除了
binhex
模块,该模块已在 Python 3.9 中弃用。 另外还移除了相关的,同样已弃用的binascii
函数binascii.a2b_hqx()
binascii.b2a_hqx()
binascii.rlecode_hqx()
binascii.rldecode_hqx()
binascii.crc_hqx()
函数仍然可用。(由 Victor Stinner 在 bpo-45085 中贡献。)
移除了在 Python 3.9 中已弃用的
distutils
bdist_msi
命令。 请改用bdist_wheel
(wheel 包)。(由 Hugo van Kemenade 在 bpo-45124 中贡献。)移除了
__getitem__()
方法,这些方法来自xml.dom.pulldom.DOMEventStream
、wsgiref.util.FileWrapper
和fileinput.FileInput
,它们自 Python 3.9 起已弃用。(由 Hugo van Kemenade 在 bpo-45132 中贡献。)移除了已弃用的
gettext
函数lgettext()
、ldgettext()
、lngettext()
和ldngettext()
。 还移除了bind_textdomain_codeset()
函数、NullTranslations.output_charset()
和NullTranslations.set_output_charset()
方法,以及translation()
和install()
的 *codeset* 参数,因为它们仅用于l*gettext()
函数。(由 Donghee Na 和 Serhiy Storchaka 在 bpo-44235 中贡献。)从
inspect
模块中移除:自 Python 3.0 起已弃用的
getargspec()
函数;请改用inspect.signature()
或inspect.getfullargspec()
。自 Python 3.5 起已弃用的
formatargspec()
函数;请直接使用inspect.signature()
函数或inspect.Signature
对象。自 Python 3.5 起已弃用的未文档化的
Signature.from_builtin()
和Signature.from_function()
方法;请改用Signature.from_callable()
方法。
(由 Hugo van Kemenade 在 bpo-45320 中贡献。)
从
pathlib.PurePath
中移除了__class_getitem__()
方法,因为它未使用并且在以前的版本中错误地添加了该方法。(由 Nikita Sobolev 在 bpo-46483 中贡献。)移除了
smtpd
模块中的MailmanProxy
类,因为它在没有外部mailman
包的情况下无法使用。(由 Donghee Na 在 bpo-35800 中贡献。)移除了已弃用的
_tkinter.TkappType
的split()
方法。(由 Erlend E. Aasland 在 bpo-38371 中贡献。)从
unittest
发现中移除了命名空间包支持。 它是在 Python 3.4 中引入的,但自 Python 3.7 起已被破坏。(由 Inada Naoki 在 bpo-23882 中贡献。)移除了未公开的私有方法
float.__set_format__()
,它在 Python 3.7 中曾被称为float.__setformat__()
。其文档字符串表示:“你可能不希望使用这个函数。它主要用于 Python 的测试套件中。”(由 Victor Stinner 贡献,详见 bpo-46852。)移除了
--experimental-isolated-subinterpreters
配置标志(以及对应的EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
宏)。Pynche — Pythonic 自然色彩和色调编辑器 — 已从
Tools/scripts
目录中移出,并独立于 Python 源代码树进行开发。
移植到 Python 3.11¶
本节列出了之前描述的更改以及 Python API 中可能需要更改 Python 代码的其他错误修复。
C API 的移植说明单独列出。
open()
、io.open()
、codecs.open()
和fileinput.FileInput
不再接受文件模式中的'U'
(“通用换行符”)。在 Python 3 中,当以文本模式打开文件时,默认使用“通用换行符”模式,而'U'
标志自 Python 3.3 起已弃用。这些函数的newline 参数控制通用换行符的工作方式。(由 Victor Stinner 贡献,详见 bpo-37330。)当提供给
compile()
和其他相关函数时,现在会验证ast.AST
节点的位置。如果检测到无效位置,将引发ValueError
。(由 Pablo Galindo 贡献,详见 gh-93351)禁止将非
concurrent.futures.ThreadPoolExecutor
执行器传递给asyncio.loop.set_default_executor()
,这遵循了 Python 3.8 中的弃用。(由 Illia Volochii 贡献,详见 bpo-43234。)calendar
:calendar.LocaleTextCalendar
和calendar.LocaleHTMLCalendar
类现在使用locale.getlocale()
,而不是使用locale.getdefaultlocale()
,如果未指定区域设置。(由 Victor Stinner 贡献,详见 bpo-46659。)pdb
模块现在使用'UTF-8'
编码读取.pdbrc
配置文件。(由 Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి) 贡献,详见 bpo-41137。)random.sample()
的 *population* 参数必须是一个序列,并且不再支持自动将set
转换为list
。此外,如果样本大小大于总体大小,则会引发ValueError
。(由 Raymond Hettinger 贡献,详见 bpo-40465。)移除了
random.shuffle()
的 *random* 可选参数。它之前是用于洗牌的任意随机函数;现在,将始终使用random.random()
(其之前的默认值)。在
re
正则表达式语法中,全局内联标志(例如(?i)
)现在只能在正则表达式的开头使用。在其他地方使用它们自 Python 3.6 起已弃用。(由 Serhiy Storchaka 贡献,详见 bpo-47066。)在
re
模块中,修复了几个长期存在的错误,这些错误在极少数情况下会导致捕获组得到错误的结果。因此,这可能会更改这些情况下的捕获输出。(由 Ma Lin 贡献,详见 bpo-35859。)
构建更改¶
CPython 现在对交叉编译到 WebAssembly 平台 Emscripten (
wasm32-unknown-emscripten
,即浏览器中的 Python) 和 WebAssembly 系统接口 (WASI) (wasm32-unknown-wasi
) 具有 PEP 11 第 3 层支持。此项工作的灵感来自以前的工作,例如 Pyodide。这些平台提供 POSIX API 的有限子集;与网络、进程、线程、信号、mmap 和用户/组相关的 Python 标准库功能和模块不可用或无法工作。(Emscripten 由 Christian Heimes 和 Ethan Smith 贡献,详见 gh-84461,WASI 由 Christian Heimes 贡献,详见 gh-90473;平台在 gh-95085 中得到提升)现在构建 CPython 需要
已移除
Py_NO_NAN
宏。由于 CPython 现在需要 IEEE 754 浮点数,因此始终可以使用 NaN 值。(由 Victor Stinner 贡献,详见 bpo-46656。)tkinter
包现在需要 Tcl/Tk 版本 8.5.12 或更高版本。(由 Serhiy Storchaka 贡献,详见 bpo-46996。)现在由 configure 检测大多数 stdlib 扩展模块的构建依赖项、编译器标志和链接器标志。libffi、libnsl、libsqlite3、zlib、bzip2、liblzma、libcrypt、Tcl/Tk 和 uuid 标志由 pkg-config 检测(如果可用)。
tkinter
现在需要 pkg-config 命令来检测 Tcl/Tk 标头和库的开发设置。(由 Christian Heimes 和 Erlend Egeberg Aasland 贡献,详见 bpo-45847、bpo-45747 和 bpo-45763。)libpython 不再链接到 libcrypt。(由 Mike Gilbert 贡献,详见 bpo-45433。)
CPython 现在可以通过将
thin
传递给--with-lto
来使用 ThinLTO 选项进行构建,即--with-lto=thin
。(由 Donghee Na 和 Brett Holman 贡献,详见 bpo-44340。)现在可以禁用对象结构的空闲列表。一个新的 configure 选项
--without-freelists
可以用来禁用除空元组单例之外的所有空闲列表。(由 Christian Heimes 在 bpo-45522 中贡献。)Modules/Setup
和Modules/makesetup
已经得到改进和整合。扩展模块现在可以通过makesetup
构建。除了某些测试模块外,所有模块都可以静态链接到主二进制文件或库中。(由 Brett Cannon 和 Christian Heimes 在 bpo-45548、bpo-45570、bpo-45571 和 bpo-43974 中贡献。)注意
使用环境变量
TCLTK_CFLAGS
和TCLTK_LIBS
手动指定 Tcl/Tk 头文件和库的位置。 configure 选项--with-tcltk-includes
和--with-tcltk-libs
已被删除。在 RHEL 7 和 CentOS 7 上,开发包不提供
tcl.pc
和tk.pc
;请使用TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5"
。目录Misc/rhel7
包含.pc
文件以及如何使用 RHEL 7 和 CentOS 7 的 Tcl/Tk 和 OpenSSL 构建 Python 的说明。CPython 现在默认对 Python
int
实现使用 30 位数字。之前,默认是在SIZEOF_VOID_P >= 8
的平台上使用 30 位数字,否则使用 15 位数字。仍然可以通过配置脚本的--enable-big-digits
选项或者(对于 Windows)PC/pyconfig.h
中的PYLONG_BITS_IN_DIGIT
变量显式请求使用 15 位数字,但此选项可能会在未来的某个时候被删除。(由 Mark Dickinson 在 bpo-45569 中贡献。)
C API 更改¶
新功能¶
添加一个新的
PyType_GetName()
函数来获取类型的短名称。(由 Hai Shi 在 bpo-42035 中贡献。)添加一个新的
PyType_GetQualName()
函数来获取类型的限定名称。(由 Hai Shi 在 bpo-42035 中贡献。)在有限的 C API 中添加新的
PyThreadState_EnterTracing()
和PyThreadState_LeaveTracing()
函数来暂停和恢复跟踪和分析。(由 Victor Stinner 在 bpo-43760 中贡献。)添加了
Py_Version
常量,其值与PY_VERSION_HEX
相同。(由 Gabriele N. Tornetta 在 bpo-43931 中贡献。)Py_buffer
和 API 现在是有限 API 和稳定 ABI 的一部分bf_getbuffer
和bf_releasebuffer
类型槽
(由 Christian Heimes 在 bpo-45459 中贡献。)
添加了
PyType_GetModuleByDef()
函数,用于在无法直接获得方法定义所在模块信息的情况下(通过PyCMethod
)获取该模块。(由 Petr Viktorin 在 bpo-46613 中贡献。)添加新函数来打包和解包 C double(序列化和反序列化):
PyFloat_Pack2()
、PyFloat_Pack4()
、PyFloat_Pack8()
、PyFloat_Unpack2()
、PyFloat_Unpack4()
和PyFloat_Unpack8()
。(由 Victor Stinner 在 bpo-46906 中贡献。)添加新函数以获取帧对象属性:
PyFrame_GetBuiltins()
、PyFrame_GetGenerator()
、PyFrame_GetGlobals()
、PyFrame_GetLasti()
。添加了两个新函数来获取和设置活动异常实例:
PyErr_GetHandledException()
和PyErr_SetHandledException()
。 这些是PyErr_SetExcInfo()
和PyErr_GetExcInfo()
的替代方案,它们使用异常的旧式 3 元组表示形式。(由 Irit Katriel 在 bpo-46343 中贡献。)添加了
PyConfig.safe_path
成员。(由 Victor Stinner 在 gh-57684 中贡献。)
移植到 Python 3.11¶
一些宏已转换为静态内联函数,以避免 宏陷阱。此更改对用户来说应该是基本透明的,因为替换函数会将其参数强制转换为预期类型,以避免由于静态类型检查导致的编译器警告。但是,当有限的 C API 设置为 >=3.11 时,这些强制转换不会执行,调用者需要将参数强制转换为其预期类型。有关更多详细信息,请参阅 PEP 670。(由 Victor Stinner 和 Erlend E. Aasland 在 gh-89653 中贡献。)
PyErr_SetExcInfo()
不再使用type
和traceback
参数,解释器现在从异常实例(value
参数)派生这些值。该函数仍然会窃取所有三个参数的引用。(由 Irit Katriel 在 bpo-45711 中贡献。)PyErr_GetExcInfo()
现在从异常实例(value
字段)派生结果的type
和traceback
字段。(由 Irit Katriel 在 bpo-45711 中贡献。)_frozen
有一个新的is_package
字段,用于指示冻结模块是否为包。之前,size
字段中的负值是指标。现在size
仅使用非负值。(由 Kumar Aditya 在 bpo-46608 中贡献。)_PyFrameEvalFunction()
现在将_PyInterpreterFrame*
作为其第二个参数,而不是PyFrameObject*
。有关如何使用此函数指针类型的更多详细信息,请参阅 PEP 523。PyCode_New()
和PyCode_NewWithPosOnlyArgs()
现在接受一个额外的exception_table
参数。如果可能的话,应该避免使用这些函数。要获取自定义代码对象:使用编译器创建一个代码对象,然后使用replace
方法获取修改后的版本。PyCodeObject
不再具有co_code
、co_varnames
、co_cellvars
和co_freevars
字段。相反,请分别使用PyCode_GetCode()
、PyCode_GetVarnames()
、PyCode_GetCellvars()
和PyCode_GetFreevars()
通过 C API 访问它们。(Brandt Bucher 在 bpo-46841 和 Ken Jin 在 gh-92154 和 gh-94936 中贡献了此更改。)旧的垃圾回收宏 (
Py_TRASHCAN_SAFE_BEGIN
/Py_TRASHCAN_SAFE_END
) 现在已弃用。它们应替换为新的宏Py_TRASHCAN_BEGIN
和Py_TRASHCAN_END
。一个具有旧宏的 tp_dealloc 函数,例如
static void mytype_dealloc(mytype *p) { PyObject_GC_UnTrack(p); Py_TRASHCAN_SAFE_BEGIN(p); ... Py_TRASHCAN_SAFE_END }
应迁移到新的宏,如下所示
static void mytype_dealloc(mytype *p) { PyObject_GC_UnTrack(p); Py_TRASHCAN_BEGIN(p, mytype_dealloc) ... Py_TRASHCAN_END }
请注意,
Py_TRASHCAN_BEGIN
具有第二个参数,该参数应为它所在的释放函数。为了在同一个代码库中支持旧版本的 Python,您可以定义以下宏并在整个代码中使用它们(感谢:这些是从
mypy
代码库中复制的)#if PY_VERSION_HEX >= 0x03080000 # define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc) # define CPy_TRASHCAN_END(op) Py_TRASHCAN_END #else # define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_SAFE_BEGIN(op) # define CPy_TRASHCAN_END(op) Py_TRASHCAN_SAFE_END(op) #endif
如果类型定义了
Py_TPFLAGS_HAVE_GC
标志但没有 traverse 函数 (PyTypeObject.tp_traverse
),则PyType_Ready()
函数现在会引发错误。(Victor Stinner 在 bpo-44263 中贡献了此更改。)具有
Py_TPFLAGS_IMMUTABLETYPE
标志的堆类型现在可以继承 PEP 590 vectorcall 协议。以前,这仅适用于 静态类型。(Erlend E. Aasland 在 bpo-43908 中贡献了此更改)由于
Py_TYPE()
已更改为内联静态函数,因此Py_TYPE(obj) = new_type
必须替换为Py_SET_TYPE(obj, new_type)
:请参阅Py_SET_TYPE()
函数(自 Python 3.9 起可用)。为了向后兼容,可以使用此宏#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { ob->ob_type = type; } #define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type) #endif
(Victor Stinner 在 bpo-39573 中贡献了此更改。)
由于
Py_SIZE()
已更改为内联静态函数,因此Py_SIZE(obj) = new_size
必须替换为Py_SET_SIZE(obj, new_size)
:请参阅Py_SET_SIZE()
函数(自 Python 3.9 起可用)。为了向后兼容,可以使用此宏#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { ob->ob_size = size; } #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) #endif
(Victor Stinner 在 bpo-39573 中贡献了此更改。)
当
Py_LIMITED_API
宏设置为0x030b0000
(Python 3.11) 或更高版本时,<Python.h>
不再包含头文件<stdlib.h>
、<stdio.h>
、<errno.h>
和<string.h>
。C 扩展应在#include <Python.h>
之后显式包含头文件。(Victor Stinner 在 bpo-45434 中贡献了此更改。)非限制 API 文件
cellobject.h
、classobject.h
、code.h
、context.h
、funcobject.h
、genobject.h
和longintrepr.h
已移动到Include/cpython
目录。此外,eval.h
头文件已被删除。这些文件不得直接包含,因为它们已包含在Python.h
中:包含文件。如果它们已被直接包含,请考虑改为包含Python.h
。(Victor Stinner 在 bpo-35134 中贡献了此更改。)PyUnicode_CHECK_INTERNED()
宏已从有限的 C API 中排除。它在那里永远不可用,因为它使用了有限的 C API 中不可用的内部结构。(Victor Stinner 在 bpo-46007 中贡献了此更改。)以下框架函数和类型现在可以通过
#include <Python.h>
直接使用,不再需要添加#include <frameobject.h>
(Victor Stinner 在 gh-93937 中贡献了此更改。)
PyFrameObject
结构的成员已从公共 C API 中删除。虽然文档指出
PyFrameObject
字段随时可能更改,但它们已经稳定了很长时间,并在几个流行的扩展中使用。在 Python 3.11 中,重新组织了帧结构以允许性能优化。一些字段被完全删除,因为它们是旧实现的细节。
f_back
:使用PyFrame_GetBack()
。f_blockstack
:已删除。f_builtins
:使用PyFrame_GetBuiltins()
。f_code
:使用PyFrame_GetCode()
。f_gen
:使用PyFrame_GetGenerator()
。f_globals
:使用PyFrame_GetGlobals()
。f_iblock
:已删除。f_lasti
:使用PyFrame_GetLasti()
。 将f_lasti
与PyCode_Addr2Line()
一起使用的代码应改为使用PyFrame_GetLineNumber()
;它可能更快。f_lineno
:使用PyFrame_GetLineNumber()
f_locals
:使用PyFrame_GetLocals()
。f_stackdepth
:已删除。f_state
:没有公共 API(重命名为f_frame.f_state
)。f_trace
:没有公共 API。f_trace_lines
:使用PyObject_GetAttrString((PyObject*)frame, "f_trace_lines")
。f_trace_opcodes
: 使用PyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")
。f_localsplus
: 没有公共 API(已重命名为f_frame.localsplus
)。f_valuestack
: 已移除。
Python 帧对象现在是延迟创建的。一个副作用是,不能直接访问
f_back
成员,因为它的值现在也是延迟计算的。必须调用PyFrame_GetBack()
函数来代替。直接访问
f_locals
的调试器必须调用PyFrame_GetLocals()
来代替。他们不再需要调用PyFrame_FastToLocalsWithError()
或PyFrame_LocalsToFast()
,事实上,他们不应该调用这些函数。帧的必要更新现在由虚拟机管理。在 Python 3.8 及更早版本上定义
PyFrame_GetCode()
的代码#if PY_VERSION_HEX < 0x030900B1 static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) { Py_INCREF(frame->f_code); return frame->f_code; } #endif
在 Python 3.8 及更早版本上定义
PyFrame_GetBack()
的代码#if PY_VERSION_HEX < 0x030900B1 static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) { Py_XINCREF(frame->f_back); return frame->f_back; } #endif
或者使用 pythoncapi_compat 项目在旧版本的 Python 上获取这两个函数。
PyThreadState
结构成员的更改frame
: 已移除,使用PyThreadState_GetFrame()
(此函数在 Python 3.9 中由 bpo-40429 添加)。警告:该函数返回一个 强引用,需要调用Py_XDECREF()
。tracing
: 已更改,使用PyThreadState_EnterTracing()
和PyThreadState_LeaveTracing()
(此函数在 Python 3.11 中由 bpo-43760 添加)。recursion_depth
: 已移除,使用(tstate->recursion_limit - tstate->recursion_remaining)
代替。stackcheck_counter
: 已移除。
在 Python 3.8 及更早版本上定义
PyThreadState_GetFrame()
的代码#if PY_VERSION_HEX < 0x030900B1 static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { Py_XINCREF(tstate->frame); return tstate->frame; } #endif
在 Python 3.10 及更早版本上定义
PyThreadState_EnterTracing()
和PyThreadState_LeaveTracing()
的代码#if PY_VERSION_HEX < 0x030B00A2 static inline void PyThreadState_EnterTracing(PyThreadState *tstate) { tstate->tracing++; #if PY_VERSION_HEX >= 0x030A00A1 tstate->cframe->use_tracing = 0; #else tstate->use_tracing = 0; #endif } static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) { int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); tstate->tracing--; #if PY_VERSION_HEX >= 0x030A00A1 tstate->cframe->use_tracing = use_tracing; #else tstate->use_tracing = use_tracing; #endif } #endif
或者使用 pythoncapi-compat 项目 在旧版本的 Python 函数上获取这些函数。
鼓励发行商使用优化的 Blake2 库 libb2 构建 Python。
现在必须将
PyConfig.module_search_paths_set
字段设置为 1,以便初始化使用PyConfig.module_search_paths
来初始化sys.path
。否则,初始化将重新计算路径并替换添加到module_search_paths
的任何值。PyConfig_Read()
不再计算初始搜索路径,并且不会在PyConfig.module_search_paths
中填充任何值。要计算默认路径然后修改它们,请完成初始化并使用PySys_GetObject()
来检索sys.path
作为 Python 列表对象并直接修改它。
已弃用¶
弃用以下用于配置 Python 初始化的函数
PySys_AddWarnOptionUnicode()
PySys_AddWarnOption()
PySys_AddXOption()
PySys_HasWarnOptions()
PySys_SetArgvEx()
PySys_SetArgv()
PySys_SetPath()
Py_SetPath()
Py_SetProgramName()
Py_SetPythonHome()
Py_SetStandardStreamEncoding()
_Py_SetProgramFullPath()
使用
PyConfig
API,即 Python 初始化配置 来代替 (PEP 587)。 (由 Victor Stinner 在 gh-88279 中贡献。)弃用
PyBytesObject
的ob_shash
成员。使用PyObject_Hash()
代替。(由 Inada Naoki 在 bpo-46864 中贡献。)
在 Python 3.12 中待移除¶
以下 C API 在较早版本的 Python 中已弃用,并将在 Python 3.12 中移除。
PyUnicode_AS_DATA()
PyUnicode_AS_UNICODE()
PyUnicode_AsUnicodeAndSize()
PyUnicode_AsUnicode()
PyUnicode_FromUnicode()
PyUnicode_GET_DATA_SIZE()
PyUnicode_GET_SIZE()
PyUnicode_GetSize()
PyUnicode_IS_COMPACT()
PyUnicode_IS_READY()
PyUnicode_WSTR_LENGTH()
_PyUnicode_AsUnicode()
PyUnicode_WCHAR_KIND
PyUnicode_InternImmortal()
已移除¶
PyFrame_BlockSetup()
和PyFrame_BlockPop()
已移除。(由 Mark Shannon 在 bpo-40222 中贡献。)移除以下使用
errno
变量的数学宏Py_ADJUST_ERANGE1()
Py_ADJUST_ERANGE2()
Py_OVERFLOWED()
Py_SET_ERANGE_IF_OVERFLOW()
Py_SET_ERRNO_ON_MATH_ERROR()
(由 Victor Stinner 在 bpo-45412 中贡献。)
移除
Py_UNICODE_COPY()
和Py_UNICODE_FILL()
宏,这些宏自 Python 3.3 起已弃用。使用PyUnicode_CopyCharacters()
或memcpy()
(wchar_t*
字符串),以及PyUnicode_Fill()
函数代替。(由 Victor Stinner 在 bpo-41123 中贡献。)移除
pystrhex.h
头文件。它只包含私有函数。C 扩展应仅包含主<Python.h>
头文件。(由 Victor Stinner 在 bpo-45434 中贡献。)移除
Py_FORCE_DOUBLE()
宏。它被Py_IS_INFINITY()
宏使用。(由 Victor Stinner 在 bpo-45440 中贡献。)定义
Py_LIMITED_API
时,以下项不再可用Py_MARSHAL_VERSION
宏
这些不属于 受限 API。
(由 Victor Stinner 在 bpo-45474 中贡献。)
从受限 C API 中排除
PyWeakref_GET_OBJECT()
。它从未起作用,因为在受限 C API 中PyWeakReference
结构是不透明的。(由 Victor Stinner 在 bpo-35134 中贡献。)移除
PyHeapType_GET_MEMBERS()
宏。它被错误地暴露在公共 C API 中,它必须仅供 Python 内部使用。使用PyTypeObject.tp_members
成员代替。(由 Victor Stinner 在 bpo-40170 中贡献。)移除
HAVE_PY_SET_53BIT_PRECISION
宏(已移至内部 C API)。(由 Victor Stinner 在 bpo-45412 中贡献。)
移除
Py_UNICODE
编码器 API,因为它们自 Python 3.3 起已弃用,使用较少,并且相对于推荐的替代方案效率低下。删除的函数是
PyUnicode_Encode()
PyUnicode_EncodeASCII()
PyUnicode_EncodeLatin1()
PyUnicode_EncodeUTF7()
PyUnicode_EncodeUTF8()
PyUnicode_EncodeUTF16()
PyUnicode_EncodeUTF32()
PyUnicode_EncodeUnicodeEscape()
PyUnicode_EncodeRawUnicodeEscape()
PyUnicode_EncodeCharmap()
PyUnicode_TranslateCharmap()
PyUnicode_EncodeDecimal()
PyUnicode_TransformDecimalToASCII()
3.11.4 中的显著变化¶
tarfile¶
tarfile
和shutil.unpack_archive()
中的提取方法新增了一个 filter 参数,用于限制可能令人意外或危险的 tar 功能,例如在目标目录之外创建文件。有关详细信息,请参阅 提取过滤器。在 Python 3.12 中,不使用 filter 参数将会显示DeprecationWarning
。在 Python 3.14 中,默认值将切换为'data'
。(由 Petr Viktorin 在 PEP 706 中贡献。)
3.11.5 中的显著变化¶
OpenSSL¶
来自 python.org 的 Windows 构建版本和 macOS 安装程序现在使用 OpenSSL 3.0。