Python 3.12 的新功能¶
- 编辑::
Adam Turner
本文解释了 Python 3.12 中相对于 3.11 的新功能。Python 3.12 于 2023 年 10 月 2 日发布。有关完整详细信息,请参阅更改日志。
另请参阅
PEP 693 – Python 3.12 发布时间表
摘要 – 版本亮点¶
Python 3.12 是 Python 编程语言的稳定版本,对语言和标准库进行了一些更改。库的更改侧重于清理已弃用的 API、可用性和正确性。值得注意的是,distutils
包已从标准库中删除。os
和 pathlib
中的文件系统支持进行了一些改进,并且一些模块具有更好的性能。
语言更改侧重于可用性,因为 f-字符串 删除了许多限制,“你的意思是……”的建议不断改进。新的类型参数语法和type
语句提高了使用泛型类型和类型别名以及静态类型检查器的人体工程学。
本文不尝试提供所有新功能的完整规范,而是提供方便的概述。有关完整详细信息,您应该参考文档,例如库参考和语言参考。如果您想了解更改的完整实现和设计原理,请参阅特定新功能的 PEP;但请注意,一旦功能完全实现,PEP 通常不会保持最新。
新的语法功能
新的语法功能
解释器改进
PEP 669,低影响监控
Python 数据模型改进
标准库的重大改进
pathlib.Path
类现在支持子类化os
模块在 Windows 支持方面进行了一些改进针对
运行时可检查的协议
的isinstance()
检查速度提高了 2 到 20 倍asyncio
包进行了一些性能改进,一些基准测试显示速度提高了 75%。
安全改进
将
hashlib
的内置 SHA1、SHA3、SHA2-384、SHA2-512 和 MD5 实现替换为来自 HACL* 项目的形式验证代码。这些内置实现仍然是后备方案,仅在 OpenSSL 不提供它们时使用。
C API 改进
CPython 实现改进
PEP 709,推导式内联
Linux
perf
分析器的CPython 支持在受支持的平台上实现堆栈溢出保护
新的类型功能
重要的弃用、删除或限制
PEP 623:从 Python C API 中的 Unicode 对象中删除
wstr
,从而使每个str
对象的大小至少减少 8 个字节。PEP 632: 移除
distutils
包。 请参阅 迁移指南,以获取替换其提供的 API 的建议。 如果你仍然需要在 Python 3.12 及更高版本中使用distutils
,第三方 Setuptools 包会继续提供该模块。gh-95299: 在使用
venv
创建的虚拟环境中,不再预安装setuptools
。 这意味着distutils
、setuptools
、pkg_resources
和easy_install
将不再默认可用;要访问这些,请在已激活的虚拟环境中运行pip install setuptools
。asynchat
、asyncore
和imp
模块已被移除,同时还有几个unittest.TestCase
方法别名。
新特性¶
PEP 695:类型参数语法¶
在 PEP 484 下,泛型类和函数使用冗长的语法声明,这使得类型参数的作用域不明确,并且需要显式声明变异性。
PEP 695 引入了一种新的、更紧凑和明确的方式来创建 泛型类 和 函数
def max[T](args: Iterable[T]) -> T:
...
class list[T]:
def __getitem__(self, index: int, /) -> T:
...
def append(self, element: T) -> None:
...
此外,PEP 还引入了一种使用 type
语句声明 类型别名 的新方法,该语句创建 TypeAliasType
的实例
type Point = tuple[float, float]
类型别名也可以是 泛型的
type Point[T] = tuple[T, T]
新语法允许声明 TypeVarTuple
和 ParamSpec
参数,以及具有边界或约束的 TypeVar
参数
type IntFunc[**P] = Callable[P, int] # ParamSpec
type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple
type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound
type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints
通过此语法创建的类型别名的值以及类型变量的边界和约束仅在需要时进行评估(请参阅 延迟求值)。这意味着类型别名能够引用文件中稍后定义的其他类型。
通过类型参数列表声明的类型参数在声明的作用域和任何嵌套作用域内可见,但在外部作用域中不可见。例如,它们可以用于泛型类的方法的类型注释或类主体中。但是,它们不能在类定义后的模块作用域中使用。有关类型参数的运行时语义的详细描述,请参阅 类型参数列表。
为了支持这些作用域语义,引入了一种新的作用域,即 注解作用域。注解作用域在大多数情况下与函数作用域的行为类似,但在与封闭的类作用域交互时会有所不同。在 Python 3.13 中,注解 也将在注解作用域中进行评估。
有关更多详细信息,请参阅 PEP 695。
(PEP 由 Eric Traut 编写。由 Jelle Zijlstra、Eric Traut 和其他人在 gh-103764 中实现。)
PEP 701:f-字符串的句法形式化¶
PEP 701 取消了对 f-字符串 使用的一些限制。f-字符串内部的表达式组件现在可以是任何有效的 Python 表达式,包括重用与包含 f-字符串相同的引号的字符串、多行表达式、注释、反斜杠和 Unicode 转义序列。让我们详细介绍这些
引号重用:在 Python 3.11 中,重用与封闭 f-字符串相同的引号会引发
SyntaxError
,迫使用户要么使用其他可用引号(例如,如果 f-字符串使用单引号,则使用双引号或三引号)。在 Python 3.12 中,你现在可以执行以下操作>>> songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism'] >>> f"This is the playlist: {", ".join(songs)}" 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
请注意,在此更改之前,f-字符串的嵌套方式没有明确的限制,但事实上,字符串引号不能在 f-字符串的表达式组件内部重用,这使得任意嵌套 f-字符串变得不可能。事实上,这是可以编写的最嵌套的 f-字符串
>>> f"""{f'''{f'{f"{1+1}"}'}'''}""" '2'
由于现在 f-字符串可以在表达式组件内部包含任何有效的 Python 表达式,因此现在可以任意嵌套 f-字符串
>>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" '2'
多行表达式和注释:在 Python 3.11 中,f-字符串表达式必须在单行中定义,即使 f-字符串中的表达式通常可以跨越多行(例如,在多行上定义的文字列表),这使得它们更难阅读。在 Python 3.12 中,你现在可以定义跨越多行的 f-字符串,并添加内联注释
>>> f"This is the playlist: {", ".join([ ... 'Take me back to Eden', # My, my, those eyes like fire ... 'Alkaline', # Not acid nor alkaline ... 'Ascensionism' # Take to the broken skies at last ... ])}" 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
反斜杠和 Unicode 字符:在 Python 3.12 之前,f-字符串表达式不能包含任何
\
字符。这也影响了 Unicode 转义序列(例如\N{snowman}
),因为这些序列包含之前不能作为 f-字符串表达式组件一部分的\N
部分。现在,你可以定义如下的表达式>>> print(f"This is the playlist: {"\n".join(songs)}") This is the playlist: Take me back to Eden Alkaline Ascensionism >>> print(f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}") This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism
有关更多详细信息,请参阅 PEP 701。
作为此功能实现方式的积极副作用(通过 PEG 解析器 解析 f-字符串),现在 f-字符串的错误消息更加精确,并包含错误的精确位置。例如,在 Python 3.11 中,以下 f-字符串引发 SyntaxError
>>> my_string = f"{x z y}" + f"{1 + 1}"
File "<stdin>", line 1
(x z y)
^^^
SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?
但是错误消息不包含行内错误的精确位置,并且还人为地用括号括住了表达式。在 Python 3.12 中,由于 f-字符串是通过 PEG 解析器解析的,因此错误消息可以更加精确,并显示整行
>>> my_string = f"{x z y}" + f"{1 + 1}"
File "<stdin>", line 1
my_string = f"{x z y}" + f"{1 + 1}"
^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
(由 Pablo Galindo、Batuhan Taskaya、Lysandros Nikolaou、Cristián Maureira-Fredes 和 Marta Gómez 在 gh-102856 中贡献。PEP 由 Pablo Galindo、Batuhan Taskaya、Lysandros Nikolaou 和 Marta Gómez 编写。)
PEP 684:每个解释器的 GIL¶
PEP 684 引入了每个解释器的 GIL,以便现在可以为每个解释器创建一个具有唯一 GIL 的子解释器。这允许 Python 程序充分利用多核 CPU。这目前仅通过 C-API 提供,但预计 Python API 将在 3.13 中推出。
使用新的 Py_NewInterpreterFromConfig()
函数创建具有自己 GIL 的解释器
PyInterpreterConfig config = {
.check_multi_interp_extensions = 1,
.gil = PyInterpreterConfig_OWN_GIL,
};
PyThreadState *tstate = NULL;
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
if (PyStatus_Exception(status)) {
return -1;
}
/* The new interpreter is now active in the current thread. */
有关如何使用 C-API 为具有每个解释器 GIL 的子解释器的更多示例,请参阅 Modules/_xxsubinterpretersmodule.c
。
(由 Eric Snow 在 gh-104210 等中贡献。)
PEP 669:CPython 的低影响监控¶
PEP 669 定义了一个新的 API
,用于分析器、调试器和其他工具来监控 CPython 中的事件。它涵盖了广泛的事件,包括调用、返回、行、异常、跳转等等。这意味着您只需为您使用的部分付费,为近零开销的调试器和覆盖率工具提供支持。有关详细信息,请参阅 sys.monitoring
。
(由 Mark Shannon 在 gh-103082 中贡献。)
PEP 688: 使缓冲区协议可在 Python 中访问¶
PEP 688 引入了一种从 Python 代码中使用缓冲区协议的方法。实现 __buffer__()
方法的类现在可以用作缓冲区类型。
新的 collections.abc.Buffer
ABC 提供了一种表示缓冲区对象的标准方法,例如在类型注释中。新的 inspect.BufferFlags
枚举表示可用于自定义缓冲区创建的标志。(由 Jelle Zijlstra 在 gh-102500 中贡献。)
PEP 709: 推导式内联¶
字典、列表和集合推导式现在是内联的,而不是为每次推导式的执行创建一个新的单次使用函数对象。这使得推导式的执行速度提高了两倍。有关详细信息,请参阅 PEP 709。
推导式的迭代变量仍然是隔离的,不会覆盖外部作用域中同名的变量,也不会在推导式之后可见。内联确实导致了一些可见的行为变化。
回溯中不再有推导式的单独帧,并且跟踪/分析不再将推导式显示为函数调用。
symtable
模块将不再为每个推导式生成子符号表;相反,推导式的局部变量将包含在父函数的符号表中。在推导式内部调用
locals()
现在包括来自推导式外部的变量,并且不再包括推导式“参数”的合成.0
变量。当在跟踪(例如代码覆盖率测量)下运行时,直接迭代
locals()
的推导式(例如[k for k in locals()]
)可能会看到 “RuntimeError: dictionary changed size during iteration”。这与在例如for k in locals():
中看到的行为相同。要避免此错误,请先创建一个要迭代的键列表:keys = list(locals()); [k for k in keys]
。
(由 Carl Meyer 和 Vladimir Matveev 在 PEP 709 中贡献。)
改进的错误消息¶
现在,当
NameError
引发到顶层时,解释器显示的错误消息中可能会建议标准库中的模块。(由 Pablo Galindo 在 gh-98254 中贡献。)>>> sys.version_info Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'sys' is not defined. Did you forget to import 'sys'?
改进实例的
NameError
异常的错误建议。现在,如果在一个方法中引发NameError
,并且该实例的属性与异常中的名称完全相等,则建议将包括self.<NAME>
,而不是方法范围内的最接近的匹配项。(由 Pablo Galindo 在 gh-99139 中贡献。)>>> class A: ... def __init__(self): ... self.blech = 1 ... ... def foo(self): ... somethin = blech ... >>> A().foo() Traceback (most recent call last): File "<stdin>", line 1 somethin = blech ^^^^^ NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
当用户键入
import x from y
而不是from y import x
时,改进SyntaxError
错误消息。(由 Pablo Galindo 在 gh-98931 中贡献。)>>> import a.y.z from b.y.z Traceback (most recent call last): File "<stdin>", line 1 import a.y.z from b.y.z ^^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: Did you mean to use 'from ... import ...' instead?
从失败的
from <module> import <name>
语句引发的ImportError
异常现在包括基于<module>
中的可用名称的<name>
值的建议。(由 Pablo Galindo 在 gh-91058 中贡献。)>>> from collections import chainmap Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
其他语言更改¶
现在,当解析包含空字节的源代码时,解析器会引发
SyntaxError
。(由 Pablo Galindo 在 gh-96670 中贡献。)现在,不是有效的转义序列的反斜杠字符对会生成
SyntaxWarning
,而不是DeprecationWarning
。例如,re.compile("\d+\.\d+")
现在会发出一个SyntaxWarning
("\d"
是无效的转义序列,对正则表达式使用原始字符串:re.compile(r"\d+\.\d+")
)。在未来的 Python 版本中,最终将引发SyntaxError
,而不是SyntaxWarning
。(由 Victor Stinner 在 gh-98401 中贡献。)八进制转义符的值大于
0o377
(例如:"\477"
),在 Python 3.11 中已被弃用,现在会产生一个SyntaxWarning
,而不是DeprecationWarning
。在未来的 Python 版本中,它们最终会成为一个SyntaxError
。(由 Victor Stinner 在 gh-98401 中贡献。)在推导式目标部分中使用的、未存储的变量现在可以在赋值表达式中使用(
:=
)。例如,在[(b := 1) for a, b.prop in some_iter]
中,现在允许对b
进行赋值。请注意,按照 PEP 572 的规定,仍然不允许对推导式目标部分中存储的变量进行赋值(如a
)。(由 Nikita Sobolev 在 gh-100581 中贡献。)在类或类型的
__set_name__
方法中引发的异常不再被RuntimeError
包裹。上下文信息会作为 PEP 678 注释添加到异常中。(由 Irit Katriel 在 gh-77757 中贡献。)当
try-except*
结构处理整个ExceptionGroup
并引发另一个异常时,该异常不再被包裹在ExceptionGroup
中。此项更改也出现在 3.11.4 版本中。(由 Irit Katriel 在 gh-103590 中贡献。)垃圾回收器现在仅在 Python 字节码评估循环的 eval 断路器机制上运行,而不是在对象分配时运行。当调用
PyErr_CheckSignals()
时,GC 也可以运行,因此需要长时间运行而不执行任何 Python 代码的 C 扩展也有机会定期执行 GC。(由 Pablo Galindo 在 gh-97922 中贡献。)所有期望布尔参数的内置函数和扩展函数现在接受任何类型的参数,而不仅仅是
bool
和int
。(由 Serhiy Storchaka 在 gh-60203 中贡献。)memoryview
现在支持半精度浮点类型(“e” 格式代码)。(由 Donghee Na 和 Antoine Pitrou 在 gh-90751 中贡献。)slice
对象现在是可哈希的,允许它们用作字典键和集合项。(由 Will Bradshaw、Furkan Onder 和 Raymond Hettinger 在 gh-101264 中贡献。)sum()
现在使用 Neumaier 求和来提高对浮点数或混合整数和浮点数求和时的准确性和交换性。(由 Raymond Hettinger 在 gh-100425 中贡献。)当解析包含空字节的源代码时,
ast.parse()
现在会引发SyntaxError
,而不是ValueError
。(由 Pablo Galindo 在 gh-96670 中贡献。)tarfile
中的提取方法和shutil.unpack_archive()
有一个新的 *filter* 参数,允许限制可能令人惊讶或危险的 tar 功能,例如在目标目录之外创建文件。有关详细信息,请参阅 tarfile 提取过滤器。在 Python 3.14 中,默认值将切换为'data'
。(由 Petr Viktorin 在 PEP 706 中贡献。)如果底层映射是可哈希的,则
types.MappingProxyType
实例现在是可哈希的。(由 Serhiy Storchaka 在 gh-87995 中贡献。)通过新的环境变量
PYTHONPERFSUPPORT
和命令行选项-X perf
以及新的sys.activate_stack_trampoline()
、sys.deactivate_stack_trampoline()
和sys.is_stack_trampoline_active()
函数,添加了 对 perf profiler 的支持。(由 Pablo Galindo 设计。由 Pablo Galindo 和 Christian Heimes 贡献,并得到 Gregory P. Smith [Google] 和 Mark Shannon 在 gh-96123 中的贡献。)
新模块¶
无。
改进的模块¶
array¶
array.array
类现在支持下标操作,使其成为 泛型类型。(由 Jelle Zijlstra 在 gh-98658 中贡献。)
asyncio¶
在
asyncio
中写入套接字的性能得到了显著提升。asyncio
现在在写入套接字时避免不必要的复制,并在平台支持的情况下使用sendmsg()
。(由 Kumar Aditya 在 gh-91166 中贡献。)添加了
asyncio.eager_task_factory()
和asyncio.create_eager_task_factory()
函数,以允许选择一个事件循环来进行 eager 任务执行,使某些用例的速度提高 2 到 5 倍。(由 Jacob Bower & Itamar Oren 在 gh-102853、gh-104140 和 gh-104138 中贡献)在 Linux 上,如果
os.pidfd_open()
可用且功能正常,则asyncio
默认使用asyncio.PidfdChildWatcher
而不是asyncio.ThreadedChildWatcher
。(由 Kumar Aditya 在 gh-98024 中贡献。)现在,事件循环会为每个平台使用最佳可用的子进程监视器(如果支持则使用
asyncio.PidfdChildWatcher
,否则使用asyncio.ThreadedChildWatcher
),因此不建议手动配置子进程监视器。(由 Kumar Aditya 在 gh-94597 中贡献。)为
asyncio.run()
添加了 loop_factory 参数,以允许指定自定义事件循环工厂。(由 Kumar Aditya 在 gh-99388 中贡献。)添加了
asyncio.current_task()
的 C 实现,以实现 4 到 6 倍的加速。(由 Itamar Oren 和 Pranav Thulasiram Bhat 在 gh-100344 中贡献。)现在,
asyncio.iscoroutine()
对于生成器返回False
,因为asyncio
不支持基于旧式生成器的协程。(由 Kumar Aditya 在 gh-102748 中贡献。)asyncio.wait()
和asyncio.as_completed()
现在接受产生任务的生成器。(由 Kumar Aditya 在 gh-78530 中贡献。)
日历¶
添加了枚举
calendar.Month
和calendar.Day
,用于定义一年中的月份和一周中的天数。(由 Prince Roshan 在 gh-103636 中贡献。)
csv¶
添加了
csv.QUOTE_NOTNULL
和csv.QUOTE_STRINGS
标志,以便通过reader
和writer
对象更精细地控制None
和空字符串。
dis¶
伪指令操作码(由编译器使用但不出现在可执行字节码中)现在在
dis
模块中公开。HAVE_ARGUMENT
仍然与实际操作码相关,但它对于伪指令没有用。请改用新的dis.hasarg
集合。(由 Irit Katriel 在 gh-94216 中贡献。)添加了
dis.hasexc
集合,以表示设置异常处理程序的指令。(由 Irit Katriel 在 gh-94216 中贡献。)
fractions¶
现在,
fractions.Fraction
类型的对象支持浮点样式格式化。(由 Mark Dickinson 在 gh-100161 中贡献。)
importlib.resources¶
现在,
importlib.resources.as_file()
支持资源目录。(由 Jason R. Coombs 在 gh-97930 中贡献。)将
importlib.resources.files()
的第一个参数重命名为 anchor。(由 Jason R. Coombs 在 gh-100598 中贡献。)
inspect¶
添加了
inspect.markcoroutinefunction()
,用于标记返回 协程 的同步函数,以便与inspect.iscoroutinefunction()
一起使用。(由 Carlton Gibson 在 gh-99247 中贡献。)添加了
inspect.getasyncgenstate()
和inspect.getasyncgenlocals()
,用于确定异步生成器的当前状态。(由 Thomas Krennwallner 在 gh-79940 中贡献。)大大提高了
inspect.getattr_static()
的性能。大多数对该函数的调用应该比 Python 3.11 中的速度快至少 2 倍。(由 Alex Waygood 在 gh-103193 中贡献。)
itertools¶
添加了
itertools.batched()
,用于收集到大小均匀的元组中,其中最后一个批次可能比其余的短。(由 Raymond Hettinger 在 gh-98363 中贡献。)
math¶
添加了
math.sumprod()
,用于计算乘积之和。(由 Raymond Hettinger 在 gh-100485 中贡献。)扩展了
math.nextafter()
以包括 steps 参数,用于一次向上或向下移动多个步骤。(由 Matthias Goergens、Mark Dickinson 和 Raymond Hettinger 在 gh-94906 中贡献。)
os¶
添加了
os.PIDFD_NONBLOCK
,用于在非阻塞模式下使用os.pidfd_open()
为进程打开文件描述符。(由 Kumar Aditya 在 gh-93312 中贡献。)现在,
os.DirEntry
包括os.DirEntry.is_junction()
方法,用于检查条目是否为连接点。(由 Charles Machalow 在 gh-99547 中贡献。)在 Windows 上添加了
os.listdrives()
、os.listvolumes()
和os.listmounts()
函数,用于枚举驱动器、卷和挂载点。(由 Steve Dower 在 gh-102519 中贡献。)现在,
os.stat()
和os.lstat()
在 Windows 上更加准确。st_birthtime
字段现在将填充文件的创建时间,并且st_ctime
已弃用,但仍然包含创建时间(但将来将返回最后一次元数据更改,以与其他平台保持一致)。st_dev
可能最多为 64 位,st_ino
可能最多为 128 位,具体取决于您的文件系统,并且st_rdev
始终设置为零而不是不正确的值。这两个函数在新版本的 Windows 上可能会明显更快。(由 Steve Dower 在 gh-99726 中贡献。)
os.path¶
添加了
os.path.isjunction()
,用于检查给定路径是否为连接点。(由 Charles Machalow 在 gh-99547 中贡献。)添加了
os.path.splitroot()
,用于将路径拆分为三元组(drive, root, tail)
。(由 Barney Gale 在 gh-101000 中贡献。)
pathlib¶
增加对子类化
pathlib.PurePath
和pathlib.Path
,以及它们特定于 Posix 和 Windows 的变体的支持。子类可以重写pathlib.PurePath.with_segments()
方法,以在路径实例之间传递信息。添加
pathlib.Path.walk()
用于遍历目录树并生成其中的所有文件或目录名称,类似于os.walk()
。(由 Stanislav Zmiev 在 gh-90385 中贡献。)向
pathlib.PurePath.relative_to()
添加可选参数 walk_up,以允许在结果中插入..
条目;这种行为与os.path.relpath()
更一致。(由 Domenico Ragusa 在 gh-84538 中贡献。)添加
pathlib.Path.is_junction()
作为os.path.isjunction()
的代理。(由 Charles Machalow 在 gh-99547 中贡献。)向
pathlib.Path.glob()
、pathlib.Path.rglob()
和pathlib.PurePath.match()
添加可选参数 case_sensitive,用于匹配路径的大小写敏感性,从而更精确地控制匹配过程。
pdb¶
添加方便的变量以临时保存调试会话的值,并提供对当前帧或返回值等值的快速访问。(由 Tian Gao 在 gh-103693 中贡献。)
random¶
添加
random.binomialvariate()
。(由 Raymond Hettinger 在 gh-81620 中贡献。)向
random.expovariate()
添加默认值lambd=1.0
。(由 Raymond Hettinger 在 gh-100234 中贡献。)
shutil¶
shutil.make_archive()
现在将 root_dir 参数传递给支持它的自定义归档器。在这种情况下,它不再临时将进程的当前工作目录更改为 root_dir 来执行归档。(由 Serhiy Storchaka 在 gh-74696 中贡献。)shutil.rmtree()
现在接受一个新参数 onexc,它是一个错误处理程序,类似于 onerror,但期望的是一个异常实例而不是 (typ, val, tb) 三元组。onerror 已被弃用。(由 Irit Katriel 在 gh-102828 中贡献。)shutil.which()
现在会查询 PATHEXT 环境变量,以便在 Windows 上即使给定的 cmd 包含目录组件时,也能在 PATH 中找到匹配项。(由 Charles Machalow 在 gh-103179 中贡献。)shutil.which()
在 Windows 上查询可执行文件时,将调用NeedCurrentDirectoryForExePathW
,以确定当前工作目录是否应添加到搜索路径中。(由 Charles Machalow 在 gh-103179 中贡献。)shutil.which()
将返回一个与 cmd 匹配的路径,该路径在 Windows 上从搜索路径的其他直接匹配之前,包含来自PATHEXT
的组件。(由 Charles Machalow 在 gh-103179 中贡献。)
sqlite3¶
向
sqlite3.Connection
添加sqlite3.Connection.autocommit
属性,并向sqlite3.connect()
添加 autocommit 参数,以控制符合 PEP 249 的 事务处理。(由 Erlend E. Aasland 在 gh-83638 中贡献。)向
sqlite3.Connection.load_extension()
添加仅关键字参数 entrypoint,用于覆盖 SQLite 扩展入口点。(由 Erlend E. Aasland 在 gh-103015 中贡献。)向
sqlite3.Connection
添加sqlite3.Connection.getconfig()
和sqlite3.Connection.setconfig()
,以便对数据库连接进行配置更改。(由 Erlend E. Aasland 在 gh-103489 中贡献。)
statistics¶
扩展
statistics.correlation()
,使其包含一个ranked
方法,用于计算排名数据的 Spearman 相关性。(由 Raymond Hettinger 在 gh-95861 中贡献。)
sys¶
添加
sys.monitoring
命名空间,以公开新的 PEP 669 监控 API。(由 Mark Shannon 在 gh-103082 中贡献。)添加
sys.activate_stack_trampoline()
和sys.deactivate_stack_trampoline()
用于激活和停用堆栈分析器跳转,以及sys.is_stack_trampoline_active()
用于查询堆栈分析器跳转是否处于活动状态。(由 Pablo Galindo 和 Christian Heimes 贡献,并得到了 Gregory P. Smith [Google] 和 Mark Shannon 的贡献,在 gh-96123 中贡献。)添加
sys.last_exc
,用于保存最后引发但未处理的异常(用于事后调试)。弃用以传统形式保存相同信息的三个字段:sys.last_type
、sys.last_value
和sys.last_traceback
。(由 Irit Katriel 在 gh-102778 中贡献。)sys._current_exceptions()
现在返回一个从线程 ID 到异常实例的映射,而不是到一个(typ, exc, tb)
元组。(由 Irit Katriel 在 gh-103176 中贡献。)sys.setrecursionlimit()
和sys.getrecursionlimit()
。 递归限制现在仅适用于 Python 代码。内置函数不使用递归限制,而是受另一种机制保护,该机制可以防止递归导致虚拟机崩溃。
tempfile¶
tempfile.NamedTemporaryFile
函数有一个新的可选参数 delete_on_close (由 Evgeny Zorin 在 gh-58451 中贡献。)tempfile.mkdtemp()
现在总是返回绝对路径,即使提供给 dir 参数的参数是相对路径。
threading¶
添加
threading.settrace_all_threads()
和threading.setprofile_all_threads()
,允许在除调用线程之外的所有正在运行的线程中设置跟踪和分析函数。(由 Pablo Galindo 在 gh-93503 中贡献。)
tkinter¶
tkinter.Canvas.coords()
现在扁平化其参数。它现在不仅接受坐标作为单独的参数 (x1, y1, x2, y2, ...
) 和坐标序列 ([x1, y1, x2, y2, ...]
),还接受成对分组的坐标 ((x1, y1), (x2, y2), ...
和[(x1, y1), (x2, y2), ...]
),例如create_*()
方法。(由 Serhiy Storchaka 在 gh-94473 中贡献。)
tokenize¶
tokenize
模块包含在 PEP 701 中引入的更改。(由 Marta Gómez Macías 和 Pablo Galindo 在 gh-102856 中贡献。) 有关tokenize
模块的更改的更多信息,请参见 迁移到 Python 3.12。
types¶
添加
types.get_original_bases()
,以便在子类化时进一步内省 用户定义泛型类型。(由 James Hilton-Balfe 和 Alex Waygood 在 gh-101827 中贡献。)
typing¶
针对
运行时可检查协议
的isinstance()
检查现在使用inspect.getattr_static()
而不是hasattr()
来查找属性是否存在。这意味着在针对运行时可检查协议进行isinstance()
检查期间,描述符和__getattr__()
方法将不再被意外评估。 但是,这也可能意味着某些曾经被认为是运行时可检查协议的实例的对象可能不再被视为 Python 3.12+ 上该协议的实例,反之亦然。 大多数用户不太可能受到此更改的影响。(由 Alex Waygood 在 gh-102433 中贡献。)运行时可检查协议的成员现在在创建类后立即被视为在运行时“冻结”。将属性修补到运行时可检查协议上仍然有效,但不会影响将对象与协议进行比较的
isinstance()
检查。 例如>>> from typing import Protocol, runtime_checkable >>> @runtime_checkable ... class HasX(Protocol): ... x = 1 ... >>> class Foo: ... ... >>> f = Foo() >>> isinstance(f, HasX) False >>> f.x = 1 >>> isinstance(f, HasX) True >>> HasX.y = 2 >>> isinstance(f, HasX) # unchanged, even though HasX now also has a "y" attribute True
进行此更改是为了加快针对运行时可检查协议的
isinstance()
检查。针对
运行时可检查协议
的isinstance()
检查的性能配置文件已发生重大变化。针对只有少数成员的协议进行的isinstance()
检查应该至少比 3.11 快 2 倍,有些可能快 20 倍或更多。 但是,针对具有多个成员的协议进行的isinstance()
检查可能比 Python 3.11 慢。(由 Alex Waygood 在 gh-74690 和 gh-103193 中贡献。)所有
typing.TypedDict
和typing.NamedTuple
类现在都有__orig_bases__
属性。(由 Adrian Garcia Badaracco 在 gh-103699 中贡献。)向
typing.dataclass_transform()
添加frozen_default
参数。(由 Erik De Bonte 在 gh-99957 中贡献。)
unicodedata¶
Unicode 数据库已更新至 15.0.0 版。(由 Benjamin Peterson 在 gh-96734 中贡献。)
unittest¶
添加一个 --durations
命令行选项,显示 N 个最慢的测试用例
python3 -m unittest --durations=3 lib.tests.test_threading
.....
Slowest test durations
----------------------------------------------------------------------
1.210s test_timeout (Lib.test.test_threading.BarrierTests)
1.003s test_default_timeout (Lib.test.test_threading.BarrierTests)
0.518s test_timeout (Lib.test.test_threading.EventTests)
(0.000 durations hidden. Use -v to show these durations.)
----------------------------------------------------------------------
Ran 158 tests in 9.869s
OK (skipped=3)
(由 Giampaolo Rodola 在 gh-48330 中贡献)
uuid¶
优化¶
从 Unicode 对象中删除
wstr
和wstr_length
成员。 这在 64 位平台上将对象大小减少了 8 或 16 个字节。 (PEP 623) (由 Inada Naoki 在 gh-92536 中贡献。)在构建过程中添加对使用 BOLT 二进制优化器的实验性支持,这可以将性能提高 1-5%。(由 Kevin Modzelewski 在 gh-90536 中贡献,并由 Donghee Na 在 gh-101525 中调整。)
将正则表达式替换(函数
re.sub()
和re.subn()
以及相应的re.Pattern
方法)的速度提高了 2-3 倍,针对包含组引用的替换字符串。(由 Serhiy Storchaka 在 gh-91524 中贡献。)通过延迟昂贵的字符串格式化来加速
asyncio.Task
的创建。(由 Itamar Oren 在 gh-103793 中贡献。)由于需要覆盖 PEP 701 的更改在
tokenize
模块中,tokenize.tokenize()
和tokenize.generate_tokens()
函数的速度提高了高达 64%。(由 Marta Gómez Macías 和 Pablo Galindo 在 gh-102856 中贡献。)通过新的
LOAD_SUPER_ATTR
指令,加速super()
方法调用和属性加载。(由 Carl Meyer 和 Vladimir Matveev 在 gh-103497 中贡献。)
CPython 字节码更改¶
移除
LOAD_METHOD
指令。它已合并到LOAD_ATTR
中。LOAD_ATTR
现在将像旧的LOAD_METHOD
指令一样工作,如果其操作数的低位被设置。(由 Ken Jin 在 gh-93429 中贡献。)移除
JUMP_IF_FALSE_OR_POP
和JUMP_IF_TRUE_OR_POP
指令。(由 Irit Katriel 在 gh-102859 中贡献。)移除
PRECALL
指令。(由 Mark Shannon 在 gh-92925 中贡献。)添加
BINARY_SLICE
和STORE_SLICE
指令。(由 Mark Shannon 在 gh-94163 中贡献。)添加
CALL_INTRINSIC_1
指令。(由 Mark Shannon 在 gh-99005 中贡献。)添加
CALL_INTRINSIC_2
指令。(由 Irit Katriel 在 gh-101799 中贡献。)添加
CLEANUP_THROW
指令。(由 Brandt Bucher 在 gh-90997 中贡献。)添加
END_SEND
指令。(由 Mark Shannon 在 gh-103082 中贡献。)添加
LOAD_FAST_AND_CLEAR
指令,作为 PEP 709 实现的一部分。(由 Carl Meyer 在 gh-101441 中贡献。)添加
LOAD_FAST_CHECK
指令。(由 Dennis Sweeney 在 gh-93143 中贡献。)添加
LOAD_FROM_DICT_OR_DEREF
,LOAD_FROM_DICT_OR_GLOBALS
, 和LOAD_LOCALS
操作码,作为 PEP 695 实现的一部分。移除LOAD_CLASSDEREF
操作码,它可以被LOAD_LOCALS
加上LOAD_FROM_DICT_OR_DEREF
替代。(由 Jelle Zijlstra 在 gh-103764 中贡献。)添加
LOAD_SUPER_ATTR
指令。(由 Carl Meyer 和 Vladimir Matveev 在 gh-103497 中贡献。)添加
RETURN_CONST
指令。(由 Wenyang Wang 在 gh-101632 中贡献。)
演示和工具¶
移除包含旧演示脚本的
Tools/demo/
目录。可以在 old-demos 项目中找到副本。(由 Victor Stinner 在 gh-97681 中贡献。)移除
Tools/scripts/
目录中过时的示例脚本。可以在 old-demos 项目中找到副本。(由 Victor Stinner 在 gh-97669 中贡献。)
已弃用¶
argparse
:argparse.BooleanOptionalAction
的 type、choices 和 metavar 参数已弃用,将在 3.14 中移除。(由 Nikita Sobolev 在 gh-92248 中贡献。)ast
:自 Python 3.8 以来,以下ast
功能已在文档中弃用,现在在访问或使用它们时会发出DeprecationWarning
,并将在 Python 3.14 中移除ast.Num
ast.Str
ast.Bytes
ast.NameConstant
ast.Ellipsis
请改用
ast.Constant
。(由 Serhiy Storchaka 在 gh-90953 中贡献。)-
子观察器类
asyncio.MultiLoopChildWatcher
,asyncio.FastChildWatcher
,asyncio.AbstractChildWatcher
和asyncio.SafeChildWatcher
已弃用,将在 Python 3.14 中移除。(由 Kumar Aditya 在 gh-94597 中贡献。)asyncio.set_child_watcher()
,asyncio.get_child_watcher()
,asyncio.AbstractEventLoopPolicy.set_child_watcher()
和asyncio.AbstractEventLoopPolicy.get_child_watcher()
已弃用,将在 Python 3.14 中移除。(由 Kumar Aditya 在 gh-94597 中贡献。)如果未设置当前事件循环,并且默认事件循环策略决定创建一个事件循环,则默认事件循环策略的
get_event_loop()
方法现在会发出DeprecationWarning
。(由 Serhiy Storchaka 和 Guido van Rossum 在 gh-100160 中贡献。)
calendar
:calendar.January
和calendar.February
常量已弃用,并由calendar.JANUARY
和calendar.FEBRUARY
替代。(由 Prince Roshan 在 gh-103636 中贡献。)collections.abc
:已弃用collections.abc.ByteString
。建议使用Sequence
或collections.abc.Buffer
。对于类型提示,建议使用联合类型,如bytes | bytearray
,或collections.abc.Buffer
。(由 Shantanu Jain 在 gh-91896 中贡献。)datetime
:datetime.datetime
的utcnow()
和utcfromtimestamp()
已被弃用,并将在未来版本中移除。请改用时区感知对象来表示 UTC 时间:分别调用now()
和fromtimestamp()
,并将 *tz* 参数设置为datetime.UTC
。(由 Paul Ganssle 在 gh-103857 中贡献。)email
: 弃用email.utils.localtime()
中的 *isdst* 参数。(由 Alan Williams 在 gh-72346 中贡献。)importlib.abc
: 弃用以下类,计划在 Python 3.14 中移除importlib.abc.ResourceReader
importlib.abc.Traversable
importlib.abc.TraversableResources
请改用
importlib.resources.abc
类(由 Jason R. Coombs 和 Hugo van Kemenade 在 gh-93963 中贡献。)
itertools
: 弃用对 copy、deepcopy 和 pickle 操作的支持,这些操作未文档化、效率低下、历史上存在错误且不一致。为了显著减少代码量和维护负担,将在 3.14 版本中移除此功能。(由 Raymond Hettinger 在 gh-101588 中贡献。)multiprocessing
: 在 Python 3.14 中,默认的multiprocessing
启动方法将在 Linux、BSD 和其他非 macOS POSIX 平台上更改为更安全的方法。在这些平台上,当前默认使用'fork'
(gh-84559)。添加关于此更改的运行时警告被认为过于干扰,因为大多数代码预计不会关心此问题。 当您的代码需要'fork'
时,请使用get_context()
或set_start_method()
API 来显式指定。请参阅 上下文和启动方法。pkgutil
:pkgutil.find_loader()
和pkgutil.get_loader()
已被弃用,并将在 Python 3.14 中移除;请改用importlib.util.find_spec()
。(由 Nikita Sobolev 在 gh-97850 中贡献。)pty
: 该模块有两个未文档化的master_open()
和slave_open()
函数,它们自 Python 2 起已被弃用,但在 3.12 中才获得了正确的DeprecationWarning
。 将在 3.14 中移除它们。(由 Soumendra Ganguly 和 Gregory P. Smith 在 gh-85984 中贡献。)os
:在 Windows 上,
os.stat()
和os.lstat()
返回的st_ctime
字段已被弃用。在未来版本中,它们将包含上次元数据更改时间,与其他平台保持一致。目前,它们仍然包含创建时间,该时间也可在新的st_birthtime
字段中获取。(由 Steve Dower 在 gh-99726 中贡献。)在 POSIX 平台上,当检测到从多线程进程调用
os.fork()
时,现在可能会引发DeprecationWarning
。当这样做时,与 POSIX 平台始终存在根本的不兼容性。即使此类代码似乎可以正常工作。我们添加此警告是为了引起注意,因为执行此操作的代码遇到的问题正变得越来越频繁。有关更多详细信息,请参阅os.fork()
文档,以及 关于 fork 与线程不兼容的讨论,以了解为什么我们现在向开发人员揭示这个长期存在的平台兼容性问题。
当由于使用
multiprocessing
或concurrent.futures
而出现此警告时,修复方法是使用不同的multiprocessing
启动方法,例如"spawn"
或"forkserver"
。shutil
:shutil.rmtree()
的 *onerror* 参数已被弃用;请改用 *onexc*。(由 Irit Katriel 在 gh-102828 中贡献。)-
默认适配器和转换器现已弃用。请改用适配器和转换器配方,并根据您的需要进行定制。(由 Erlend E. Aasland 在 gh-90016 中贡献。)
在
execute()
中,当命名占位符与作为序列而不是作为dict
提供的参数一起使用时,现在会发出DeprecationWarning
。 从 Python 3.14 开始,将命名占位符与作为序列提供的参数一起使用将引发ProgrammingError
。(由 Erlend E. Aasland 在 gh-101698 中贡献。)
sys
:sys.last_type
、sys.last_value
和sys.last_traceback
字段已弃用。请改用sys.last_exc
。(由 Irit Katriel 在 gh-102778 中贡献。)tarfile
:在 Python 3.14 之前,提取 tar 归档文件而不指定 filter 将被弃用,届时'data'
过滤器将成为默认值。有关详细信息,请参阅 提取过滤器。-
typing.Hashable
和typing.Sized
,分别是collections.abc.Hashable
和collections.abc.Sized
的别名,已被弃用。(gh-94309。)typing.ByteString
,自 Python 3.9 起已弃用,现在使用时会发出DeprecationWarning
。(由 Alex Waygood 在 gh-91896 中贡献。)
xml.etree.ElementTree
:该模块现在在测试xml.etree.ElementTree.Element
的真值时发出DeprecationWarning
。以前,Python 实现发出FutureWarning
,而 C 实现则不发出任何警告。(由 Jacob Walls 在 gh-83122 中贡献。)coroutine throw()
、generator throw()
和async generator throw()
的 3 参数签名(类型、值、回溯)已被弃用,并且可能会在未来版本的 Python 中删除。请改用这些函数的单参数版本。(由 Ofey Chan 在 gh-89874 中贡献。)当模块上的
__package__
与__spec__.parent
不同时,现在会引发DeprecationWarning
(以前是ImportWarning
)。(由 Brett Cannon 在 gh-65961 中贡献。)在模块上设置
__package__
或__cached__
已被弃用,并且在 Python 3.14 中将不再被导入系统设置或考虑。(由 Brett Cannon 在 gh-65961 中贡献。)布尔值的按位反转运算符 (
~
) 已被弃用。它将在 Python 3.16 中引发错误。请改用not
对布尔值进行逻辑否定。在您确实需要底层int
的按位反转的极少数情况下,请显式转换为 int:~int(x)
。(由 Tim Hoffmann 在 gh-103487 中贡献。)通过 PEP 626,在 Python 3.10 中已弃用访问代码对象上的
co_lnotab
,但在 3.12 中才得到了适当的DeprecationWarning
。可能会在 3.15 中删除。(由 Nikita Sobolev 在 gh-101866 中贡献。)
Python 3.13 中待移除的内容¶
模块(请参阅 PEP 594)
aifc
audioop
cgi
cgitb
chunk
crypt
imghdr
mailcap
msilib
nis
nntplib
ossaudiodev
pipes
sndhdr
spwd
sunau
telnetlib
uu
xdrlib
其他模块
lib2to3
和 2to3 程序 (gh-84540)
API
configparser.LegacyInterpolation
(gh-90765)locale.resetlocale()
(gh-90817)turtle.RawTurtle.settiltangle()
(gh-50096)unittest.findTestCases()
(gh-50096)unittest.getTestCaseNames()
(gh-50096)unittest.makeSuite()
(gh-50096)unittest.TestProgram.usageExit()
(gh-67048)webbrowser.MacOSX
(gh-86421)classmethod
描述符链 (gh-89519)importlib.resources
弃用的方法contents()
is_resource()
open_binary()
open_text()
path()
read_binary()
read_text()
请改用
importlib.resources.files()
。请参阅 importlib-resources:从旧版本迁移 (gh-106531)
Python 3.14 中待移除的内容¶
argparse
:argparse.BooleanOptionalAction
的 type、choices 和 metavar 参数已弃用,将在 3.14 中移除。(由 Nikita Sobolev 在 gh-92248 中贡献。)ast
:以下功能自 Python 3.8 起已在文档中弃用,现在在访问或使用它们时会在运行时发出DeprecationWarning
,并且将在 Python 3.14 中删除ast.Num
ast.Str
ast.Bytes
ast.NameConstant
ast.Ellipsis
请改用
ast.Constant
。(由 Serhiy Storchaka 在 gh-90953 中贡献。)-
子进程监视器类
MultiLoopChildWatcher
、FastChildWatcher
、AbstractChildWatcher
和SafeChildWatcher
已被弃用,将在 Python 3.14 中移除。(由 Kumar Aditya 在 gh-94597 中贡献。)asyncio.set_child_watcher()
,asyncio.get_child_watcher()
,asyncio.AbstractEventLoopPolicy.set_child_watcher()
和asyncio.AbstractEventLoopPolicy.get_child_watcher()
已弃用,将在 Python 3.14 中移除。(由 Kumar Aditya 在 gh-94597 中贡献。)如果未设置当前事件循环,并且默认事件循环策略决定创建一个事件循环,则默认事件循环策略的
get_event_loop()
方法现在会发出DeprecationWarning
。(由 Serhiy Storchaka 和 Guido van Rossum 在 gh-100160 中贡献。)
collections.abc
: 已弃用ByteString
。 建议使用Sequence
或Buffer
。 对于类型提示,建议使用联合类型,如bytes | bytearray
,或collections.abc.Buffer
。(由 Shantanu Jain 在 gh-91896 中贡献。)email
: 弃用了email.utils.localtime()
中的 isdst 参数。(由 Alan Williams 在 gh-72346 中贡献。)importlib.abc
弃用类importlib.abc.ResourceReader
importlib.abc.Traversable
importlib.abc.TraversableResources
请改用
importlib.resources.abc
类(由 Jason R. Coombs 和 Hugo van Kemenade 在 gh-93963 中贡献。)
itertools
对 copy、deepcopy 和 pickle 操作的支持是未文档化、效率低下、历史上存在 bug 且不一致的。 为了大幅减少代码量和维护负担,此支持将在 3.14 中移除。(由 Raymond Hettinger 在 gh-101588 中贡献。)multiprocessing
: 在 Linux、BSDs 和其他非 macOS POSIX 平台上,默认启动方法将更改为更安全的方法,其中当前'fork'
是默认方法 (gh-84559)。 添加关于此的运行时警告被认为太具破坏性,因为大多数代码预计不会在意。 如果你的代码需要'fork'
,请使用get_context()
或set_start_method()
API 来显式指定。 请参阅 上下文和启动方法。pathlib
:is_relative_to()
和relative_to()
: 传递额外的参数已被弃用。pkgutil
:find_loader()
和get_loader()
现在会引发DeprecationWarning
;请改用importlib.util.find_spec()
。(由 Nikita Sobolev 在 gh-97850 中贡献。)pty
:master_open()
: 请使用pty.openpty()
。slave_open()
: 请使用pty.openpty()
。
-
如果使用 命名占位符 并且 parameters 是序列而不是
dict
,则execute()
和executemany()
。
typing
:ByteString
自 Python 3.9 起已被弃用,现在在使用时会发出DeprecationWarning
。urllib
:urllib.parse.Quoter
已被弃用:它不应作为公共 API。(由 Gregory P. Smith 在 gh-88168 中贡献。)
计划在 Python 3.15 中移除¶
导入系统
在未能设置
__spec__.cached
的情况下在模块上设置__cached__
已被弃用。 在 Python 3.15 中,导入系统或标准库将停止设置或考虑__cached__
。(gh-97879)在未能设置
__spec__.parent
的情况下在模块上设置__package__
已被弃用。 在 Python 3.15 中,导入系统或标准库将停止设置或考虑__package__
。(gh-97879)
-
未文档化的
ctypes.SetPointerType()
函数自 Python 3.13 起已被弃用。
-
自 Python 3.13 起,过时且很少使用的
CGIHTTPRequestHandler
已被弃用。 没有直接的替代品。 任何东西都比 CGI 更好,可以将 Web 服务器与请求处理程序连接起来。自 Python 3.13 起,python -m http.server 命令行界面的
--cgi
标志已被弃用。
-
自 Python 3.11 起,
getdefaultlocale()
函数已被弃用。其移除最初计划在 Python 3.13 中进行 (gh-90817),但已推迟至 Python 3.15。请改用getlocale()
、setlocale()
和getencoding()
。(由 Hugo van Kemenade 在 gh-111187 中贡献。)
-
自 Python 3.13 起,
PurePath.is_reserved()
已被弃用。请使用os.path.isreserved()
来检测 Windows 上的保留路径。
-
自 Python 3.13 起,
java_ver()
已被弃用。此函数仅对 Jython 支持有用,具有令人困惑的 API,并且基本上未经测试。
-
RLock()
在 Python 3.15 中将不接受任何参数。自 Python 3.14 起,传递任何参数都已被弃用,因为 Python 版本不允许任何参数,但 C 版本允许任何数量的位置参数或关键字参数,并忽略每个参数。
-
types.CodeType
: 访问co_lnotab
在 PEP 626 中自 3.10 起已弃用,并计划在 3.12 中删除,但它仅在 3.12 中获得了正确的DeprecationWarning
。可能会在 3.15 中删除。(由 Nikita Sobolev 在 gh-101866 中贡献。)
-
用于创建
NamedTuple
类的未文档化的关键字参数语法(例如Point = NamedTuple("Point", x=int, y=int)
)自 Python 3.13 起已被弃用。请改用基于类的语法或函数式语法。自 Python 3.13 起,
typing.no_type_check_decorator()
装饰器函数已被弃用。在typing
模块中存在八年后,它仍然未被任何主要的类型检查器支持。
wave
:getmark()
、setmark()
和getmarkers()
方法,它们属于Wave_read
和Wave_write
类,自 Python 3.13 起已被弃用。
计划在 Python 3.16 中移除¶
导入系统
在未能设置
__spec__.loader
的同时设置模块的__loader__
已被弃用。在 Python 3.16 中,导入系统或标准库将不再设置或考虑__loader__
。
-
自 Python 3.3 起,文档中已弃用
'u'
格式代码 (wchar_t
),自 Python 3.13 起,运行时已弃用。请改用'w'
格式代码 (Py_UCS4
) 来表示 Unicode 字符。
-
asyncio.iscoroutinefunction()
已被弃用,将在 Python 3.16 中删除,请改用inspect.iscoroutinefunction()
。(由 Jiahao Li 和 Kumar Aditya 在 gh-122875 中贡献。)
-
对布尔类型进行按位反转,例如
~True
或~False
,自 Python 3.12 起已被弃用,因为它会产生令人惊讶且不直观的结果(-2
和-1
)。对于布尔值的逻辑非,请改用not x
。在极少数情况下,如果您需要底层整数的按位反转,请显式转换为int
(~int(x)
)。
-
自 Python 3.14 起,
ExecError
异常已被弃用。自 Python 3.4 以来,shutil
中的任何函数都没有使用它,现在它是RuntimeError
的别名。
-
自 Python 3.14 起,
Class.get_methods
方法已被弃用。
sys
:自 Python 3.13 起,
_enablelegacywindowsfsencoding()
函数已被弃用。请改用PYTHONLEGACYWINDOWSFSENCODING
环境变量。
-
自 Python 3.13 起,未文档化且未使用的
TarFile.tarfile
属性已被弃用。
计划在未来版本中移除¶
以下 API 将在未来删除,但目前尚未安排删除日期。
argparse
:嵌套参数组和嵌套互斥组已被弃用。-
bool(NotImplemented)
.生成器:
throw(type, exc, tb)
和athrow(type, exc, tb)
签名已弃用:请改用throw(exc)
和athrow(exc)
,即单参数签名。目前,Python 允许数字字面量紧跟关键字,例如
0in x
、1or x
、0if 1else 2
。这允许出现令人困惑和模棱两可的表达式,如[0x1for x in y]
(可以解释为[0x1 for x in y]
或[0x1f or x in y]
)。如果数字字面量紧跟以下关键字之一,则会引发语法警告:and
、else
、for
、if
、in
、is
和or
。在未来的版本中,这将改为语法错误。(gh-87999)支持
__index__()
和__int__()
方法返回非 int 类型:这些方法将需要返回int
的严格子类的实例。将
int()
的调用委托给__trunc__()
方法。现在不建议将复数作为
complex()
构造函数中的 *real* 或 *imag* 参数传递;它应该只作为单个位置参数传递。(由 Serhiy Storchaka 在 gh-109218 中贡献。)
calendar
:calendar.January
和calendar.February
常量已弃用,并由calendar.JANUARY
和calendar.FEBRUARY
替代。(由 Prince Roshan 在 gh-103636 中贡献。)codeobject.co_lnotab
:请使用codeobject.co_lines()
方法代替。-
utcnow()
:请使用datetime.datetime.now(tz=datetime.UTC)
。utcfromtimestamp()
:请使用datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)
。
gettext
:复数形式的值必须是整数。-
load_module()
方法:请使用exec_module()
代替。cache_from_source()
的 *debug_override* 参数已弃用:请使用 *optimization* 参数代替。
-
EntryPoints
元组接口。返回值上的隐式
None
。
mailbox
:不推荐使用 StringIO 输入和文本模式,请使用 BytesIO 和二进制模式代替。os
:在多线程进程中调用os.register_at_fork()
。pydoc.ErrorDuringImport
:*exc_info* 参数的元组值已弃用,请使用异常实例。re
:正则表达式中的数字组引用和组名现在应用更严格的规则。现在只接受 ASCII 数字序列作为数字引用。字节模式和替换字符串中的组名现在只能包含 ASCII 字母、数字和下划线。(由 Serhiy Storchaka 在 gh-91760 中贡献。)sre_compile
、sre_constants
和sre_parse
模块。shutil
:rmtree()
的 *onerror* 参数在 Python 3.12 中已弃用;请使用 *onexc* 参数代替。ssl
选项和协议不带 protocol 参数的
ssl.SSLContext
已弃用。ssl.SSLContext
:set_npn_protocols()
和selected_npn_protocol()
已弃用:请使用 ALPN 代替。ssl.OP_NO_SSL*
选项ssl.OP_NO_TLS*
选项ssl.PROTOCOL_SSLv3
ssl.PROTOCOL_TLS
ssl.PROTOCOL_TLSv1
ssl.PROTOCOL_TLSv1_1
ssl.PROTOCOL_TLSv1_2
ssl.TLSVersion.SSLv3
ssl.TLSVersion.TLSv1
ssl.TLSVersion.TLSv1_1
sysconfig.is_python_build()
的 *check_home* 参数已弃用并被忽略。threading
方法threading.Condition.notifyAll()
:请使用notify_all()
。threading.Event.isSet()
:请使用is_set()
。threading.Thread.isDaemon()
、threading.Thread.setDaemon()
:请使用threading.Thread.daemon
属性。threading.Thread.getName()
、threading.Thread.setName()
:请使用threading.Thread.name
属性。threading.currentThread()
:请使用threading.current_thread()
。threading.activeCount()
:请使用threading.active_count()
。
unittest.IsolatedAsyncioTestCase
:从测试用例返回值(不是None
)已弃用。urllib.parse
中已弃用的函数:请使用urlparse()
代替。splitattr()
splithost()
splitnport()
splitpasswd()
splitport()
splitquery()
splittag()
splittype()
splituser()
splitvalue()
to_bytes()
urllib.request
:调用请求的URLopener
和FancyURLopener
样式已被弃用。请使用较新的urlopen()
函数和方法。wsgiref
:SimpleHandler.stdout.write()
不应进行部分写入。xml.etree.ElementTree
:测试Element
的真值已被弃用。在未来的版本中,它将始终返回True
。请首选显式的len(elem)
或elem is not None
测试。
已移除¶
asynchat 和 asyncore¶
configparser¶
早在 3.2 版本中
configparser
中弃用的几个名称已根据 gh-89336 移除configparser.ParsingError
不再具有filename
属性或参数。请改用source
属性和参数。configparser
不再具有SafeConfigParser
类。请改用较短的ConfigParser
名称。configparser.ConfigParser
不再具有readfp
方法。请改用read_file()
。
distutils¶
ensurepip¶
从
ensurepip
中删除捆绑的 setuptools wheel,并停止在由venv
创建的环境中安装 setuptools。pip (>= 22.1)
不需要在环境中安装 setuptools。setuptools
基(和distutils
基)的包仍然可以与pip install
一起使用,因为 pip 将在其用于构建包的构建环境中提供setuptools
。easy_install
、pkg_resources
、setuptools
和distutils
不再默认在由venv
创建或由ensurepip
引导的环境中提供,因为它们是setuptools
包的一部分。对于在运行时依赖这些的项目,应将setuptools
项目声明为依赖项并单独安装(通常使用 pip)。(由 Pradyun Gedam 在 gh-95299 中贡献。)
enum¶
ftplib¶
gzip¶
移除
gzip
的gzip.GzipFile
的filename
属性,该属性自 Python 2.6 起已被弃用,请改用name
属性。在写入模式下,如果不存在,filename
属性会添加'.gz'
文件扩展名。(由 Victor Stinner 在 gh-94196 中贡献。)
hashlib¶
移除
hashlib
的hashlib.pbkdf2_hmac()
的纯 Python 实现,该实现在 Python 3.10 中已被弃用。Python 3.10 及更高版本需要 OpenSSL 1.1.1 (PEP 644):此 OpenSSL 版本提供了pbkdf2_hmac()
的 C 实现,速度更快。(由 Victor Stinner 在 gh-94199 中贡献。)
importlib¶
现在已完成
importlib
中许多先前已弃用的清理工作已移除对
module_repr()
的引用和支持。(由 Barry Warsaw 在 gh-97850 中贡献。)importlib.util.set_package
、importlib.util.set_loader
和importlib.util.module_for_loader
已全部移除。(由 Brett Cannon 和 Nikita Sobolev 在 gh-65961 和 gh-97850 中贡献。)已移除对
find_loader()
和find_module()
API 的支持。(由 Barry Warsaw 在 gh-98040 中贡献。)importlib.abc.Finder
、pkgutil.ImpImporter
和pkgutil.ImpLoader
已被移除。(由 Barry Warsaw 在 gh-98040 中贡献。)
imp¶
imp
模块已被移除。(由 Barry Warsaw 在 gh-98040 中贡献。)要进行迁移,请查阅以下对应表
imp
importlib
imp.NullImporter
将
None
插入到sys.path_importer_cache
中imp.cache_from_source()
imp.find_module()
imp.get_magic()
imp.get_suffixes()
importlib.machinery.SOURCE_SUFFIXES
、importlib.machinery.EXTENSION_SUFFIXES
和importlib.machinery.BYTECODE_SUFFIXES
imp.get_tag()
imp.load_module()
imp.new_module(name)
types.ModuleType(name)
imp.reload()
imp.source_from_cache()
imp.load_source()
见下文
将
imp.load_source()
替换为import importlib.util import importlib.machinery def load_source(modname, filename): loader = importlib.machinery.SourceFileLoader(modname, filename) spec = importlib.util.spec_from_file_location(modname, filename, loader=loader) module = importlib.util.module_from_spec(spec) # The module is always executed and not cached in sys.modules. # Uncomment the following line to cache the module. # sys.modules[module.__name__] = module loader.exec_module(module) return module
移除没有替代的
imp
函数和属性未文档化的函数
imp.init_builtin()
imp.load_compiled()
imp.load_dynamic()
imp.load_package()
imp.lock_held()
、imp.acquire_lock()
、imp.release_lock()
:Python 3.3 中锁定方案已更改为每个模块锁定。imp.find_module()
常量:SEARCH_ERROR
、PY_SOURCE
、PY_COMPILED
、C_EXTENSION
、PY_RESOURCE
、PKG_DIRECTORY
、C_BUILTIN
、PY_FROZEN
、PY_CODERESOURCE
、IMP_HOOK
。
io¶
locale¶
移除
locale
的locale.format()
函数,它在 Python 3.7 中已弃用:请改用locale.format_string()
。(由 Victor Stinner 在 gh-94226 中贡献。)
smtpd¶
sqlite3¶
以下未文档化的
sqlite3
功能在 Python 3.10 中已弃用,现在已被删除sqlite3.enable_shared_cache()
sqlite3.OptimizedUnicode
如果必须使用共享缓存,请使用
cache=shared
查询参数以 URI 模式打开数据库。自 Python 3.3 以来,
sqlite3.OptimizedUnicode
文本工厂一直是str
的别名。先前将文本工厂设置为OptimizedUnicode
的代码可以显式使用str
,或者依赖于默认值,该值也是str
。(由 Erlend E. Aasland 在 gh-92548 中贡献。)
ssl¶
移除
ssl
的ssl.RAND_pseudo_bytes()
函数,它在 Python 3.6 中已弃用:请改用os.urandom()
或ssl.RAND_bytes()
。(由 Victor Stinner 在 gh-94199 中贡献。)移除
ssl.match_hostname()
函数。它在 Python 3.7 中已弃用。自 Python 3.7 以来,OpenSSL 执行主机名匹配,Python 不再使用ssl.match_hostname()
函数。(由 Victor Stinner 在 gh-94199 中贡献。)移除
ssl.wrap_socket()
函数,它在 Python 3.7 中已弃用:请改为创建一个ssl.SSLContext
对象并调用其ssl.SSLContext.wrap_socket
方法。任何仍然使用ssl.wrap_socket()
的软件包都是损坏且不安全的。该函数既不发送 SNI TLS 扩展,也不验证服务器主机名。代码容易受到 CWE 295 (不正确的证书验证)的影响。(由 Victor Stinner 在 gh-94199 中贡献。)
unittest¶
移除许多长期弃用的
unittest
功能许多
TestCase
方法别名已弃用的别名
方法名称
已弃用版本
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
您可以使用 https://github.com/isidentical/teyit 来自动现代化您的单元测试。
未文档化且已损坏的
TestCase
方法assertDictContainsSubset
(在 Python 3.2 中已弃用)。未文档化的
TestLoader.loadTestsFromModule
参数 use_load_tests (自 Python 3.5 起已弃用并被忽略)。TextTestResult
类的别名:_TextTestResult
(在 Python 3.2 中已弃用)。
(由 Serhiy Storchaka 在 gh-89325 中贡献。)
webbrowser¶
从
webbrowser
中移除对过时浏览器的支持。移除的浏览器包括:Grail、Mosaic、Netscape、Galeon、Skipstone、Iceape、Firebird 和 35 及以下版本的 Firefox ( gh-102871 )。
xml.etree.ElementTree¶
移除纯 Python 实现的
ElementTree.Element.copy()
方法,该方法在 Python 3.10 中已弃用,请改用copy.copy()
函数。xml.etree.ElementTree
的 C 实现没有copy()
方法,只有一个__copy__()
方法。(由 Victor Stinner 在 gh-94383 中贡献。)
zipimport¶
其他¶
从文档
Makefile
和Doc/tools/rstlint.py
中删除suspicious
规则,这两个文件都支持 sphinx-lint。(由 Julien Palard 在 gh-98179 中贡献。)从
ftplib
、imaplib
、poplib
和smtplib
模块中移除 keyfile 和 certfile 参数,以及从http.client
模块中移除 key_file、cert_file 和 check_hostname 参数,这些参数自 Python 3.6 起已弃用。请改用 context 参数(imaplib
中的 ssl_context)。(由 Victor Stinner 在 gh-94172 中贡献。)从多个 stdlib 模块和测试中删除
Jython
兼容性 hack。(由 Nikita Sobolev 在 gh-99482 中贡献。)从
ctypes
模块中移除_use_broken_old_ctypes_structure_semantics_
标志。(由 Nikita Sobolev 在 gh-99285 中贡献。)
移植到 Python 3.12¶
本节列出了先前描述的更改和其他错误修复,这些更改可能需要您修改代码。
Python API 中的更改¶
现在对正则表达式中的数字组引用和组名称应用了更严格的规则。现在只接受 ASCII 数字序列作为数字引用。字节模式和替换字符串中的组名称现在只能包含 ASCII 字母和数字以及下划线。(由 Serhiy Storchaka 在 gh-91760 中贡献。)
移除自 Python 3.10 起已弃用的
randrange()
功能。以前,randrange(10.0)
会无损地转换为randrange(10)
。现在,它会引发TypeError
。此外,对于非整数值(例如randrange(10.5)
或randrange('10')
)引发的异常已从ValueError
更改为TypeError
。这也防止了randrange(1e25)
会静默地从比randrange(10**25)
更大的范围中进行选择的错误。(最初由 Serhiy Storchaka 建议 gh-86388。)argparse.ArgumentParser
更改了从文件读取参数(例如fromfile_prefix_chars
选项)的编码和错误处理程序,从默认文本编码(例如locale.getpreferredencoding(False)
)更改为 文件系统编码和错误处理程序。在 Windows 上,参数文件应使用 UTF-8 而不是 ANSI 代码页进行编码。移除在 Python 3.4.7 和 3.5.4 中已弃用的基于
asyncore
的smtpd
模块。推荐的替代方案是基于asyncio
的 aiosmtpd PyPI 模块。shlex.split()
:为 s 参数传递None
现在会引发异常,而不是读取sys.stdin
。该功能在 Python 3.9 中已弃用。(由 Victor Stinner 在 gh-94352 中贡献。)os
模块不再接受类似字节的路径,例如bytearray
和memoryview
类型:对于字节字符串,仅接受精确的bytes
类型。(由 Victor Stinner 在 gh-98393 中贡献。)如果子解释器中使用
syslog.openlog()
和syslog.closelog()
,现在会失败。syslog.syslog()
仍然可以在子解释器中使用,但前提是必须在主解释器中先调用过syslog.openlog()
。 这些新的限制不适用于主解释器,因此只有极少数用户可能会受到影响。 此更改有助于解释器隔离。 此外,syslog
是对进程全局资源的包装,最好从主解释器进行管理。(由 Donghee Na 在 gh-99127 中贡献。)cached_property()
未记录的锁定行为已被移除,因为它会跨类的所有实例进行锁定,导致高锁争用。 这意味着,如果两个线程竞争,则缓存属性的 getter 函数现在可能会为单个实例运行多次。 对于大多数简单的缓存属性(例如,那些是幂等且仅根据实例的其他属性计算值的属性),这不会有问题。 如果需要同步,请在缓存属性的 getter 函数中或在多线程访问点周围实现锁定。sys._current_exceptions()
现在返回一个从线程 ID 到异常实例的映射,而不是到一个(typ, exc, tb)
元组。(由 Irit Katriel 在 gh-103176 中贡献。)当使用
tarfile
或shutil.unpack_archive()
解压缩 tar 文件时,请传递 filter 参数以限制可能令人意外或危险的功能。 有关详细信息,请参阅 提取过滤器。由于 PEP 701 中引入的更改,
tokenize.tokenize()
和tokenize.generate_tokens()
函数的输出现在已更改。 这意味着,不再为 f 字符串发出STRING
标记,而是会生成 PEP 701 中描述的标记:除了表达式组件中标记化的相应标记外,现在还会为 f 字符串的“字符串”部分发出FSTRING_START
、FSTRING_MIDDLE
和FSTRING_END
。 例如,对于 f 字符串f"start {1+1} end"
,旧版本的标记器发出1,0-1,18: STRING 'f"start {1+1} end"'
而新版本发出
1,0-1,2: FSTRING_START 'f"' 1,2-1,8: FSTRING_MIDDLE 'start ' 1,8-1,9: OP '{' 1,9-1,10: NUMBER '1' 1,10-1,11: OP '+' 1,11-1,12: NUMBER '1' 1,12-1,13: OP '}' 1,13-1,17: FSTRING_MIDDLE ' end' 1,17-1,18: FSTRING_END '"'
此外,由于支持 PEP 701 所需的更改,可能还会出现一些细微的行为更改。 其中一些更改包括
当标记化某些无效的 Python 字符(如
!
)时,发出的标记的type
属性已从ERRORTOKEN
更改为OP
。不完整的单行字符串现在也会像不完整的多行字符串一样引发
tokenize.TokenError
。某些不完整或无效的 Python 代码现在在标记化时会引发
tokenize.TokenError
,而不是返回任意的ERRORTOKEN
标记。不再支持在同一文件中混合使用制表符和空格作为缩进,并且会引发
TabError
。
threading
模块现在期望_thread
模块具有_is_main_interpreter
属性。 它是一个没有参数的函数,如果当前解释器是主解释器,则返回True
。任何提供自定义
_thread
模块的库或应用程序都应提供_is_main_interpreter()
。(请参阅 gh-112826。)
构建更改¶
Python 不再使用
setup.py
来构建共享的 C 扩展模块。 构建参数(如头文件和库)在configure
脚本中检测。 扩展由Makefile
构建。 大多数扩展使用pkg-config
,并回退到手动检测。(由 Christian Heimes 在 gh-93939 中贡献。)现在需要使用两个参数的
va_start()
(如va_start(args, format)
)来构建 Python。 不再使用单个参数调用va_start()
。(由 Kumar Aditya 在 gh-93207 中贡献。)如果 Clang 编译器接受该标志,CPython 现在默认使用 ThinLTO 选项作为链接时优化策略。(由 Donghee Na 在 gh-89536 中贡献。)
在
Makefile
中添加COMPILEALL_OPTS
变量以覆盖compileall
选项(默认值:-j0
),用于make install
。 还将 3 个compileall
命令合并为一个命令,以一次为所有优化级别(0、1、2)构建 .pyc 文件。(由 Victor Stinner 在 gh-99289 中贡献。)为 64 位 LoongArch 添加平台三元组
loongarch64-linux-gnusf
loongarch64-linux-gnuf32
loongarch64-linux-gnu
(由 Zhang Na 在 gh-90656 中贡献。)
PYTHON_FOR_REGEN
现在需要 Python 3.10 或更高版本。现在需要 Autoconf 2.71 和 aclocal 1.16.4 来重新生成
!configure
。(由 Christian Heimes 在 gh-89886 中贡献。)来自 python.org 的 Windows 构建和 macOS 安装程序现在使用 OpenSSL 3.0。
C API 更改¶
新功能¶
PEP 697:引入 不稳定 C API 层,该层适用于调试器和 JIT 编译器等底层工具。 此 API 可能会在 CPython 的每个次要版本中更改,而无需弃用警告。 其内容在名称中以
PyUnstable_
前缀标记。代码对象构造函数
PyUnstable_Code_New()
(从PyCode_New
重命名)PyUnstable_Code_NewWithPosOnlyArgs()
(从PyCode_NewWithPosOnlyArgs
重命名)
代码对象的额外存储 (PEP 523)
PyUnstable_Eval_RequestCodeExtraIndex()
(从_PyEval_RequestCodeExtraIndex
重命名)PyUnstable_Code_GetExtra()
(从_PyCode_GetExtra
重命名)PyUnstable_Code_SetExtra()
(从_PyCode_SetExtra
重命名)
原始名称将继续可用,直到各自的 API 更改。
(由 Petr Viktorin 在 gh-101101 中贡献。)
PEP 697:添加用于扩展实例内存布局不透明的类型的 API
PyType_Spec.basicsize
可以为零或负数,以指定继承或扩展基类大小。添加了
PyObject_GetTypeData()
和PyType_GetTypeDataSize()
,以允许访问子类特定的实例数据。添加了
Py_TPFLAGS_ITEMS_AT_END
和PyObject_GetItemData()
,以允许安全地扩展某些可变大小的类型,包括PyType_Type
。添加了
Py_RELATIVE_OFFSET
,以允许根据子类特定的结构定义members
。
(由 Petr Viktorin 在 gh-103509 中贡献。)
添加了新的 有限 C API 函数
PyType_FromMetaclass()
,它使用额外的元类参数推广了现有的PyType_FromModuleAndSpec()
。(由 Wenzel Jakob 在 gh-93012 中贡献。)用于创建可以使用 vectorcall 协议 调用的对象的 API 已添加到 有限 API
当类的
__call__()
方法被重新赋值时,Py_TPFLAGS_HAVE_VECTORCALL
标志现在会从类中删除。这使得 vectorcall 可以安全地用于可变类型(即没有不可变标志的堆类型,Py_TPFLAGS_IMMUTABLETYPE
)。不重写tp_call
的可变类型现在会继承Py_TPFLAGS_HAVE_VECTORCALL
标志。(由 Petr Viktorin 在 gh-93274 中贡献。)添加了
Py_TPFLAGS_MANAGED_DICT
和Py_TPFLAGS_MANAGED_WEAKREF
标志。这允许扩展类以更少的记账,使用更少的内存和更快的访问来支持对象__dict__
和弱引用。用于使用 vectorcall 协议 执行调用的 API 已添加到 有限 API
这意味着 vector call 协议的传入和传出端现在都可以在 有限 API 中使用。(由 Wenzel Jakob 在 gh-98586 中贡献。)
添加了两个新的公共函数
PyEval_SetProfileAllThreads()
和PyEval_SetTraceAllThreads()
,它们允许在所有正在运行的线程中设置跟踪和分析函数,以及调用线程。(由 Pablo Galindo 在 gh-93503 中贡献。)添加了新的函数
PyFunction_SetVectorcall()
到 C API,它设置给定PyFunctionObject
的 vectorcall 字段。(由 Andrew Frost 在 gh-92257 中贡献。)C API 现在允许通过
PyDict_AddWatcher()
、PyDict_Watch()
和相关的 API 注册回调,以便在字典被修改时调用。这旨在供优化解释器、JIT 编译器或调试器使用。(由 Carl Meyer 在 gh-91052 中贡献。)添加了
PyType_AddWatcher()
和PyType_Watch()
API,用于注册回调以接收类型更改的通知。(由 Carl Meyer 在 gh-91051 中贡献。)添加了
PyCode_AddWatcher()
和PyCode_ClearWatcher()
API,用于注册回调以接收代码对象的创建和销毁通知。(由 Itamar Oren 在 gh-91054 中贡献。)添加了
PyFrame_GetVar()
和PyFrame_GetVarString()
函数,用于按名称获取帧变量。(由 Victor Stinner 在 gh-91248 中贡献。)添加了
PyErr_GetRaisedException()
和PyErr_SetRaisedException()
,用于保存和恢复当前异常。这些函数返回并接受一个单一的异常对象,而不是现已弃用的PyErr_Fetch()
和PyErr_Restore()
的三个参数。这样更不容易出错,效率也更高。(由 Mark Shannon 在 gh-101578 中贡献。)添加了
_PyErr_ChainExceptions1
,它接受一个异常实例,以替换现在已弃用的旧版 API_PyErr_ChainExceptions
。(由 Mark Shannon 在 gh-101578 中贡献。)添加了
PyException_GetArgs()
和PyException_SetArgs()
作为方便函数,用于检索和修改传递给异常构造函数的args
。(由 Mark Shannon 在 gh-101578 中贡献。)添加了
PyErr_DisplayException()
,它接受一个异常实例,以替换旧版 APIPyErr_Display()
。(由 Irit Katriel 在 gh-102755 中贡献。)
PEP 683:引入不朽对象,允许对象绕过引用计数,以及 C-API 的相关更改
_Py_IMMORTAL_REFCNT
:定义对象为不朽的引用计数。为不朽。
_Py_IsImmortal
检查对象是否具有不朽的引用计数。PyObject_HEAD_INIT
现在会将引用计数初始化为_Py_IMMORTAL_REFCNT
当与Py_BUILD_CORE
一起使用时。
SSTATE_INTERNED_IMMORTAL
不朽的 interned unicode 对象的标识符。是不朽的。
SSTATE_INTERNED_IMMORTAL_STATIC
不朽且静态的 interned unicode 对象的标识符是静态的
sys.getunicodeinternedsize
这将返回已 interned 的 unicode 对象总数。现在需要这样做,以便
refleak.py
正确跟踪引用计数和已分配的块
(由 Eddie Elizondo 在 gh-84436 中贡献。)
PEP 684:添加了新的
Py_NewInterpreterFromConfig()
函数和PyInterpreterConfig
,它们可用于创建具有自己的 GIL 的子解释器。(有关更多信息,请参阅 PEP 684:每个解释器 GIL。)(由 Eric Snow 在 gh-104110 中贡献。)在有限 C API 版本 3.12 中,
Py_INCREF()
和Py_DECREF()
函数现在实现为不透明的函数调用,以隐藏实现细节。(由 Victor Stinner 在 gh-105387 中贡献。)
移植到 Python 3.12¶
已删除基于
Py_UNICODE*
表示的旧版 Unicode API。请迁移到基于 UTF-8 或wchar_t*
的 API。像
PyArg_ParseTuple()
这样的参数解析函数不再支持基于Py_UNICODE*
的格式(例如u
,Z
)。请迁移到其他 Unicode 格式,如s
、z
、es
和U
。所有静态内置类型的
tp_weaklist
始终为NULL
。这是PyTypeObject
上的一个内部字段,但我们在此指出此更改,以防有人直接访问该字段。为了避免破坏,请考虑使用现有的公共 C-API,或者在必要时使用(仅限内部的)_PyObject_GET_WEAKREFS_LISTPTR()
宏。这个仅限内部的
PyTypeObject.tp_subclasses
现在可能不再是有效的对象指针。它的类型已更改为 void* 以反映这一点。我们在此说明此更改,以防有人直接访问此仅限内部的字段。要获取子类列表,请调用 Python 方法
__subclasses__()
(例如,使用PyObject_CallMethod()
)。在
PyUnicode_FromFormat()
和PyUnicode_FromFormatV()
中添加了对更多格式化选项的支持(左对齐、八进制、大写十六进制、intmax_t
、ptrdiff_t
、wchar_t
C 字符串、可变宽度和精度)。(由 Serhiy Storchaka 在 gh-98836 中贡献。)在
PyUnicode_FromFormat()
和PyUnicode_FromFormatV()
中无法识别的格式字符现在会设置SystemError
。在以前的版本中,它会导致格式字符串的其余部分按原样复制到结果字符串,并丢弃任何额外的参数。(由 Serhiy Storchaka 在 gh-95781 中贡献。)修复了
PyUnicode_FromFormat()
和PyUnicode_FromFormatV()
中错误的符号位置。(由 Philip Georgi 在 gh-95504 中贡献。)想要添加
__dict__
或弱引用槽的扩展类应分别使用Py_TPFLAGS_MANAGED_DICT
和Py_TPFLAGS_MANAGED_WEAKREF
,而不是tp_dictoffset
和tp_weaklistoffset
。仍然支持使用tp_dictoffset
和tp_weaklistoffset
,但它并不完全支持多重继承 (gh-95589),并且性能可能会更差。声明了Py_TPFLAGS_MANAGED_DICT
的类必须调用_PyObject_VisitManagedDict()
和_PyObject_ClearManagedDict()
来遍历和清除其实例的字典。要清除弱引用,请像以前一样调用PyObject_ClearWeakRefs()
。PyUnicode_FSDecoder()
函数不再接受类似字节的路径,如bytearray
和memoryview
类型:对于字节字符串,只接受精确的bytes
类型。(由 Victor Stinner 在 gh-98393 中贡献。)Py_CLEAR
、Py_SETREF
和Py_XSETREF
宏现在只计算它们的参数一次。如果参数有副作用,这些副作用将不再重复。(由 Victor Stinner 在 gh-98724 中贡献。)解释器的错误指示器现在始终被规范化。这意味着
PyErr_SetObject()
、PyErr_SetString()
和其他设置错误指示器的函数现在会在存储异常之前将其规范化。(由 Mark Shannon 在 gh-101578 中贡献。)_Py_RefTotal
不再是权威性的,只是为了 ABI 兼容性而保留。请注意,它是一个内部全局变量,仅在调试版本中可用。如果您碰巧正在使用它,那么您需要开始使用_Py_GetGlobalRefTotal()
。以下函数现在为新创建的类型选择适当的元类:
创建其元类覆盖了
tp_new
的类已弃用,并且在 Python 3.14+ 中将被禁止。请注意,这些函数会忽略元类的tp_new
,可能会允许不完整的初始化。请注意,
PyType_FromMetaclass()
(在 Python 3.12 中添加)已经禁止创建其元类覆盖了tp_new
的类(Python 中的__new__()
)。由于
tp_new
覆盖了PyType_From*
函数所做的几乎所有事情,因此两者互不兼容。现有行为(在类型创建的几个步骤中忽略元类)通常是不安全的,因为(元)类假设已调用tp_new
。没有简单的通用解决方法。以下方法之一可能对您有效:如果您控制元类,请避免在其中使用
tp_new
如果可以跳过初始化,则可以在
tp_init
中完成初始化。如果不需要从 Python 实例化元类,请使用
Py_TPFLAGS_DISALLOW_INSTANTIATION
标志将其tp_new
设置为NULL
。这使得PyType_From*
函数可以接受它。
避免使用
PyType_From*
函数:如果您不需要 C 特有的功能(槽或设置实例大小),请通过 调用 元类来创建类型。如果您知道可以安全地跳过
tp_new
,请使用 Python 中的warnings.catch_warnings()
过滤掉弃用警告。
PyOS_InputHook
和PyOS_ReadlineFunctionPointer
不再在子解释器中调用。这是因为客户端通常依赖于进程范围的全局状态(因为这些回调无法恢复扩展模块状态)。这也避免了扩展可能发现自己在不支持(或尚未加载)的子解释器中运行的情况。有关更多信息,请参阅 gh-104668。
PyLongObject
的内部结构已更改,以获得更好的性能。尽管PyLongObject
的内部结构是私有的,但一些扩展模块会使用它们。不应再直接访问内部字段,而应使用以PyLong_...
开头的 API 函数。提供了两个新的*不稳定*API 函数,用于高效访问适合单个机器字的PyLongObject
的值:现在,无论内存域如何,通过
PyMem_SetAllocator()
设置的自定义分配器都必须是线程安全的。 那些没有自身状态的分配器(包括“钩子”)不受影响。 如果你的自定义分配器还不是线程安全的,并且需要指导,请创建一个新的 GitHub issue 并抄送@ericsnowcurrently
。
已弃用¶
根据 PEP 699,
PyDictObject
中的ma_version_tag
字段已被扩展模块弃用。 访问此字段将在编译时生成编译器警告。 此字段将在 Python 3.14 中删除。(由 Ramvikrams 和 Kumar Aditya 在 gh-101193 中贡献。Ken Jin 的 PEP。)弃用全局配置变量
Py_HashRandomizationFlag
: 使用PyConfig.use_hash_seed
和PyConfig.hash_seed
Py_LegacyWindowsFSEncodingFlag
: 使用PyPreConfig.legacy_windows_fs_encoding
Py_FileSystemDefaultEncoding
: 使用PyConfig.filesystem_encoding
Py_HasFileSystemDefaultEncoding
: 使用PyConfig.filesystem_encoding
Py_FileSystemDefaultEncodeErrors
: 使用PyConfig.filesystem_errors
Py_UTF8Mode
: 使用PyPreConfig.utf8_mode
(请参阅Py_PreInitialize()
)
应该将
Py_InitializeFromConfig()
API 与PyConfig
一起使用。(由 Victor Stinner 在 gh-77782 中贡献。)使用可变基类创建
immutable types
已被弃用,将在 Python 3.14 中禁用。(gh-95388)structmember.h
标头已弃用,但它将继续可用,并且没有计划将其删除。现在只需包含
Python.h
即可使用其内容,如果缺少Py
前缀,则会添加该前缀类型宏,如
Py_T_INT
,Py_T_DOUBLE
等(以前为T_INT
,T_DOUBLE
等)标志
Py_READONLY
(以前为READONLY
)和Py_AUDIT_READ
(以前全部为大写)
有些项没有从
Python.h
中公开T_NONE
(以前未记录,而且非常奇怪)不做任何事的宏
WRITE_RESTRICTED
。宏
RESTRICTED
和READ_RESTRICTED
,相当于Py_AUDIT_READ
。在某些配置中,
Python.h
中不包含<stddef.h>
。 使用offsetof()
时应手动包含它。
已弃用的标头继续以原始名称提供其原始内容。 你的旧代码可以保持不变,除非额外的包含和非命名空间宏让你非常困扰。
(由 Petr Viktorin 在 gh-47146 中贡献,基于 Alexander Belopolsky 和 Matthias Braun 的早期工作。)
PyErr_Fetch()
和PyErr_Restore()
已弃用。请改用PyErr_GetRaisedException()
和PyErr_SetRaisedException()
。(由 Mark Shannon 在 gh-101578 中贡献。)PyErr_Display()
已弃用。请改用PyErr_DisplayException()
。(由 Irit Katriel 在 gh-102755 中贡献)。_PyErr_ChainExceptions
已弃用。请改用_PyErr_ChainExceptions1
。(由 Irit Katriel 在 gh-102192 中贡献。)使用
PyType_FromSpec()
、PyType_FromSpecWithBases()
或PyType_FromModuleAndSpec()
创建元类覆盖了tp_new
的类已弃用。请改为调用元类。
Python 3.14 中待移除¶
扩展模块中
PyDictObject
的ma_version_tag
字段 (PEP 699;gh-101193)。用于配置 Python 初始化的函数,在 Python 3.11 中已弃用
PySys_SetArgvEx()
: 请改用设置PyConfig.argv
。PySys_SetArgv()
: 请改用设置PyConfig.argv
。Py_SetProgramName()
: 请改用设置PyConfig.program_name
。Py_SetPythonHome()
: 请改用设置PyConfig.home
。
应该将
Py_InitializeFromConfig()
API 与PyConfig
一起使用。全局配置变量
Py_QuietFlag
: 请改用PyConfig.quiet
。Py_HashRandomizationFlag
: 请改用PyConfig.use_hash_seed
和PyConfig.hash_seed
。Py_LegacyWindowsFSEncodingFlag
: 请改用PyPreConfig.legacy_windows_fs_encoding
。Py_LegacyWindowsStdioFlag
: 请改用PyConfig.legacy_windows_stdio
。Py_FileSystemDefaultEncoding
: 请改用PyConfig.filesystem_encoding
。Py_HasFileSystemDefaultEncoding
: 请改用PyConfig.filesystem_encoding
。Py_FileSystemDefaultEncodeErrors
: 请改用PyConfig.filesystem_errors
。Py_UTF8Mode
: 请改用PyPreConfig.utf8_mode
。(请参阅Py_PreInitialize()
)
应该将
Py_InitializeFromConfig()
API 与PyConfig
一起使用。
Python 3.15 中待移除¶
捆绑的
libmpdecimal
副本。PyWeakref_GetObject()
和PyWeakref_GET_OBJECT()
:请改用PyWeakref_GetRef()
。Py_UNICODE
类型和Py_UNICODE_WIDE
宏:请改用wchar_t
。Python 初始化函数
PySys_ResetWarnOptions()
:请改为清除sys.warnoptions
和warnings.filters
。Py_GetExecPrefix()
:请改为获取sys.base_exec_prefix
和sys.exec_prefix
。Py_GetPath()
:请改为获取sys.path
。Py_GetPrefix()
:请改为获取sys.base_prefix
和sys.prefix
。Py_GetPythonHome()
:请改为获取PyConfig.home
或PYTHONHOME
环境变量。
未来版本中待移除项¶
以下 API 已被弃用,将被移除,尽管目前尚未安排移除的日期。
Py_TPFLAGS_HAVE_FINALIZE
:自 Python 3.8 起不再需要。PySlice_GetIndicesEx()
:请改用PySlice_Unpack()
和PySlice_AdjustIndices()
。PyUnicode_AsDecodedObject()
:请改用PyCodec_Decode()
。PyUnicode_AsDecodedUnicode()
:请改用PyCodec_Decode()
。PyUnicode_AsEncodedObject()
:请改用PyCodec_Encode()
。PyUnicode_AsEncodedUnicode()
:请改用PyCodec_Encode()
。PyUnicode_READY()
:自 Python 3.12 起不再需要。PyErr_Display()
:请改用PyErr_DisplayException()
。_PyErr_ChainExceptions()
:请改用_PyErr_ChainExceptions1()
。PyBytesObject.ob_shash
成员:请改为调用PyObject_Hash()
。PyDictObject.ma_version_tag
成员。线程本地存储 (TLS) API
已移除项¶
移除
token.h
头文件。从来没有任何公共的词法分析器 C API。token.h
头文件仅供 Python 内部使用。(由 Victor Stinner 在 gh-92651 中贡献。)已移除旧版的 Unicode API。 请参阅 PEP 623 了解详情。
PyUnicode_WCHAR_KIND
PyUnicode_AS_UNICODE()
PyUnicode_AsUnicode()
PyUnicode_AsUnicodeAndSize()
PyUnicode_AS_DATA()
PyUnicode_FromUnicode()
PyUnicode_GET_SIZE()
PyUnicode_GetSize()
PyUnicode_GET_DATA_SIZE()
移除
PyUnicode_InternImmortal()
函数宏。(由 Victor Stinner 在 gh-85858 中贡献。)