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-strings 已删除了许多限制,“你的意思是……”建议也持续改进。新的类型参数语法和 type
语句改善了与静态类型检查器一起使用泛型类型和类型别名的人机工程学。
本文不试图提供所有新功能的完整规范,而是提供一个方便的概述。有关完整详细信息,您应参阅文档,例如库参考和语言参考。如果您想了解更改的完整实现和设计原理,请参阅特定新功能的 PEP;但请注意,一旦功能完全实现,PEP 通常不会保持最新。
新语法功能
新语法特性
解释器的改进
PEP 669,低影响监控
Python 数据模型改进
标准库的重大改进
pathlib.Path
类现在支持子类化os
模块在 Windows 支持方面获得了一些改进针对
运行时可检查协议
的isinstance()
检查速度提高了两到二十倍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-string 的句法形式化¶
PEP 701 解除了一些对 f-strings 使用的限制。f-string 内的表达式组件现在可以是任何有效的 Python 表达式,包括重用与包含 f-string 相同引号的字符串、多行表达式、注释、反斜杠和 Unicode 转义序列。让我们详细介绍这些内容
引号重用:在 Python 3.11 中,重用与包含 f-string 相同的引号会引发
SyntaxError
,强制用户使用其他可用引号(例如,如果 f-string 使用单引号,则使用双引号或三引号)。在 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-string 的嵌套方式没有明确限制,但字符串引号不能在 f-string 的表达式组件内重用这一事实使得任意嵌套 f-string 变得不可能。实际上,这是可以编写的最深层嵌套的 f-string
>>> f"""{f'''{f'{f"{1+1}"}'}'''}""" '2'
由于现在 f-string 可以在表达式组件内包含任何有效的 Python 表达式,因此现在可以任意嵌套 f-string
>>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" '2'
多行表达式和注释:在 Python 3.11 中,f-string 表达式必须定义在单行中,即使 f-string 中的表达式通常可以跨多行(例如,在多行上定义的字面量列表),这使得它们更难阅读。在 Python 3.12 中,您现在可以定义跨多行的 f-string,并添加行内注释
>>> 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-string 表达式不能包含任何
\
字符。这也影响了 Unicode 转义序列(例如\N{snowman}
),因为这些序列包含以前不能成为 f-string 表达式组件一部分的\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-strings),现在 f-string 的错误消息更精确,并包含错误的精确位置。例如,在 Python 3.11 中,以下 f-string 会引发 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-strings 是用 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 提供,尽管 预计 3.13 将提供 Python API。
使用新的 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
抽象基类提供了一种表示缓冲区对象的标准方式,例如在类型注释中。新的 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 中贡献。)在 Python 3.11 中已弃用的大于
0o377
的八进制转义(例如:"\477"
),现在会生成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 字节码评估循环的评估断路器机制上运行,而不是对象分配。GC 也可以在调用
PyErr_CheckSignals()
时运行,因此需要长时间运行而无需执行任何 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 分析器的支持。(由 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()
函数,以允许事件循环选择启用渴望任务执行,从而使某些用例速度提高 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¶
添加枚举
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 中至少快两倍。(由 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 可选参数,用于匹配路径的大小写敏感性,从而更精确地控制匹配过程。
platform¶
增加对检测 Windows 11 和 Windows Server 2012 以后版本的支持。此前,在 Windows Server 2012 以后和 Windows 11 上的查询会返回
Windows-10
。(由 Steve Dower 在 gh-89545 中贡献。)
pdb¶
添加方便变量以在调试会话中临时保存值,并提供对当前帧或返回值等值的快速访问。(由 Tian Gao 在 gh-103693 中贡献。)
random¶
添加
random.binomialvariate()
。(由 Raymond Hettinger 在 gh-81620 中贡献。)将
lambd=1.0
添加为random.expovariate()
的默认值。(由 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 环境变量,即使给定的 cmd 包含目录组件,也会在 Windows 上的 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.autocommit
属性添加到sqlite3.Connection
,并将 autocommit 参数添加到sqlite3.connect()
,以控制符合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()
对runtime-checkable protocols
的检查现在使用inspect.getattr_static()
而不是hasattr()
来查找属性是否存在。这意味着描述符和__getattr__()
方法在对可运行时检查协议进行isinstance()
检查时不再意外求值。然而,这也可能意味着一些过去被认为是可运行时检查协议实例的对象,在 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()
检查。对
runtime-checkable protocols
的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 贡献)。作为
tokenize
模块中覆盖 PEP 701 所需更改的副作用,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
:以下ast
功能自 Python 3.8 起已在文档中弃用,现在在运行时访问或使用时会发出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
已弃用。要测试
obj
是否在运行时实现了缓冲区协议,请使用isinstance(obj, collections.abc.Buffer)
。在类型注解中,请使用Buffer
或显式指定代码支持的类型的联合类型(例如bytes | bytearray | memoryview
)。ByteString
最初旨在作为bytes
和bytearray
的超类型。然而,由于 ABC 从未有任何方法,知道一个对象是ByteString
的实例实际上并不能告诉你任何关于该对象的有用信息。其他常见的缓冲区类型,如memoryview
,也从未被理解为ByteString
的子类型(无论是运行时还是静态类型检查器)。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
:弃用了对复制、深复制和 pickle 操作的支持,这些操作未文档化、效率低下、历史上存在 bug 且不一致。这将从 3.14 中移除,以显著减少代码量和维护负担。(由 Raymond Hettinger 在 gh-101588 贡献)。multiprocessing
:在 Python 3.14 中,在 Linux、BSD 和其他非 macOS POSIX 平台上(目前默认为'fork'
),multiprocessing
的默认启动方法将更改为更安全的方法 (gh-84559)。添加运行时警告被认为过于具有破坏性,因为大多数代码预计不会关心。使用get_context()
或set_start_method()
API 显式指定您的代码何时 *需要*'fork'
。请参阅 上下文和启动方法。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
:os.stat()
和os.lstat()
在 Windows 上返回的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 之前,未指定 filter 来提取 tar 归档文件已弃用,届时'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()
的三参数签名(类型、值、回溯)已弃用,并可能在 Python 的未来版本中移除。请改用这些函数的单参数版本。(由 Ofey Chan 在 gh-89874 贡献)。当模块上的
__package__
与__spec__.parent
不同时,现在会引发DeprecationWarning
(以前是ImportWarning
)。(由 Brett Cannon 在 gh-65961 贡献)。在模块上设置
__package__
或__cached__
已弃用,并且在 Python 3.14 中将不再由导入系统设置或考虑。(由 Brett Cannon 在 gh-65961 贡献)。对 bool 类型使用按位反转运算符(
~
)已弃用。它将在 Python 3.16 中引发错误。请改用not
对 bool 进行逻辑非操作。在极少数情况下,如果您确实需要底层int
的按位反转,请显式转换为 int:~int(x)
。(由 Tim Hoffmann 在 gh-103487 贡献)。在 Python 3.10 中,通过 PEP 626 弃用了代码对象上的
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 贡献)。-
子进程观察器类
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 贡献)。
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
对复制、深复制和 pickle 操作的支持未文档化、效率低下、历史上存在 bug 且不一致。这将从 3.14 中移除,以显著减少代码量和维护负担。(由 Raymond Hettinger 在 gh-101588 贡献)。multiprocessing
:在 Linux、BSD 和其他非 macOS POSIX 平台上(目前默认为'fork'
),默认启动方法将更改为更安全的方法 (gh-84559)。添加运行时警告被认为过于具有破坏性,因为大多数代码预计不会关心。使用get_context()
或set_start_method()
API 显式指定您的代码何时 *需要*'fork'
。请参阅 上下文和启动方法。pathlib
:is_relative_to()
和relative_to()
:传递额外参数已弃用。pkgutil
:pkgutil.find_loader()
和pkgutil.get_loader()
现在会引发DeprecationWarning
;请改用importlib.util.find_spec()
。(由 Nikita Sobolev 在 gh-97850 贡献)。pty
:master_open()
:请使用pty.openpty()
。slave_open()
:请使用pty.openpty()
。
-
version
和version_info
。execute()
和executemany()
,如果使用了 命名占位符 并且 parameters 是一个序列而不是dict
。
urllib
:urllib.parse.Quoter
已弃用:它无意作为公共 API。(由 Gregory P. Smith 在 gh-88168 贡献)。
计划在 Python 3.15 中移除¶
导入系统
在设置模块的
__cached__
属性时,若未同时设置__spec__.cached
,此行为已被弃用。在 Python 3.15 中,导入系统或标准库将不再设置或考虑__cached__
属性。(由 gh-97879 贡献)在设置模块的
__package__
属性时,若未同时设置__spec__.parent
,此行为已被弃用。在 Python 3.15 中,导入系统或标准库将不再设置或考虑__package__
属性。(由 gh-97879 贡献)
-
未写入文档的
ctypes.SetPointerType()
函数自 Python 3.13 起已被弃用。
-
过时且很少使用的
CGIHTTPRequestHandler
已从 Python 3.13 开始弃用。没有直接的替代品。任何将 Web 服务器与请求处理程序对接的方式都比 CGI 好。python -m http.server 命令行界面的
--cgi
旗标已自 Python 3.13 起弃用。
-
load_module()
方法:请改用exec_module()
。
-
getdefaultlocale()
函数自 Python 3.11 起已弃用。原计划在 Python 3.13 中移除 (gh-90817),但已推迟到 Python 3.15。请改用getlocale()
、setlocale()
和getencoding()
。(由 Hugo van Kemenade 在 gh-111187 贡献)。
-
PurePath.is_reserved()
已自 Python 3.13 起弃用。要检测 Windows 上的保留路径,请使用os.path.isreserved()
。
-
java_ver()
已自 Python 3.13 起弃用。此函数仅对 Jython 支持有用,其 API 令人困惑,且基本未经测试。
-
sysconfig.is_python_build()
的 check_home 参数已自 Python 3.12 起弃用。
-
RLock()
在 Python 3.15 中将不再接受任何参数。自 Python 3.14 起,传递任何参数的行为已被弃用,因为 Python 版本不允许任何参数,但 C 版本允许任意数量的位置或关键字参数,并会忽略所有参数。
-
types.CodeType
:在 Python 3.10 中通过 PEP 626 弃用了co_lnotab
的访问,原计划在 3.12 中移除,但直到 3.12 才获得了适当的DeprecationWarning
。可能在 3.15 中移除。(由 Nikita Sobolev 在 gh-101866 贡献)。
-
用于创建
NamedTuple
类的未写入文档的关键字参数语法(例如,Point = NamedTuple("Point", x=int, y=int)
)已自 Python 3.13 起弃用。请改用基于类的语法或函数式语法。使用
TypedDict
的函数式语法时,未向 fields 参数传递值(TD = TypedDict("TD")
)或传递None
(TD = TypedDict("TD", None)
)自 Python 3.13 起已弃用。请使用class TD(TypedDict): pass
或TD = TypedDict("TD", {})
来创建具有零字段的 TypedDict。typing.no_type_check_decorator()
装饰器函数已自 Python 3.13 起弃用。在typing
模块中存在八年后,它仍未被任何主流类型检查器支持。
wave
:Wave_read
和Wave_write
类的getmark()
、setmark()
和getmarkers()
方法自 Python 3.13 起已弃用。
-
load_module()
已自 Python 3.10 起弃用。请改用exec_module()
。(由 Jiahao Li 在 gh-125746 中贡献。)
计划在 Python 3.16 中移除¶
导入系统
在设置模块的
__loader__
属性时,若未同时设置__spec__.loader
,此行为已被弃用。在 Python 3.16 中,导入系统或标准库将不再设置或考虑__loader__
属性。
-
'u'
格式代码(wchar_t
)自 Python 3.3 起在文档中被弃用,自 Python 3.13 起在运行时被弃用。请改用'w'
格式代码(Py_UCS4
)来处理 Unicode 字符。
-
asyncio.iscoroutinefunction()
已被弃用,并将在 Python 3.16 中移除;请改用inspect.iscoroutinefunction()
。(由 Jiahao Li 和 Kumar Aditya 在 gh-122875 中贡献。)asyncio
的策略系统已被弃用,并将在 Python 3.16 中移除。特别是,以下类和函数已被弃用:用户应使用
asyncio.run()
或带 loop_factory 参数的asyncio.Runner
来使用期望的事件循环实现。例如,在 Windows 上使用
asyncio.SelectorEventLoop
import asyncio async def main(): ... asyncio.run(main(), loop_factory=asyncio.SelectorEventLoop)
(由 Kumar Aditya 在 gh-127949 中贡献。)
-
对布尔类型进行按位取反(
~True
或~False
)的行为已自 Python 3.12 起弃用,因为它会产生令人惊讶且不直观的结果(-2
和-1
)。要对布尔值进行逻辑非运算,请改用not x
。在极少数情况下,如果您需要对底层整数进行按位取反,请显式转换为int
(~int(x)
)。
-
以关键字参数形式向
functools.reduce()
的 Python 实现传递 function 或 sequence 参数的做法已自 Python 3.14 起弃用。
-
对带有 strm 参数的自定义日志处理程序的支持已被弃用,并计划在 Python 3.16 中移除。请改用 stream 参数来定义处理程序。(由 Mariusz Felisiak 在 gh-115032 中贡献。)
-
对于
mimetypes.MimeTypes.add_type()
,有效的扩展名应以“.”开头或是空字符串。不带点的扩展名已被弃用,并将在 Python 3.16 中引发ValueError
。(由 Hugo van Kemenade 在 gh-75223 中贡献。)
-
ExecError
异常已自 Python 3.14 起弃用。自 Python 3.4 以来,shutil
中的任何函数都未使用过它,现在它是RuntimeError
的别名。
-
Class.get_methods
方法已自 Python 3.14 起弃用。
sys
:_enablelegacywindowsfsencoding()
函数自 Python 3.13 起已弃用。请改用PYTHONLEGACYWINDOWSFSENCODING
环境变量。
-
sysconfig.expand_makefile_vars()
函数已自 Python 3.14 起弃用。请改用sysconfig.get_paths()
的vars
参数。
-
未写入文档且未使用的
TarFile.tarfile
属性已自 Python 3.13 起弃用。
计划在 Python 3.17 中移除¶
-
collections.abc.ByteString
计划在 Python 3.17 中移除。要测试
obj
是否在运行时实现了缓冲区协议,请使用isinstance(obj, collections.abc.Buffer)
。在类型注解中,请使用Buffer
或显式指定代码支持的类型的联合类型(例如bytes | bytearray | memoryview
)。ByteString
最初旨在作为bytes
和bytearray
的超类型。然而,由于 ABC 从未有任何方法,知道一个对象是ByteString
的实例实际上并不能告诉你任何关于该对象的有用信息。其他常见的缓冲区类型,如memoryview
,也从未被理解为ByteString
的子类型(无论是运行时还是静态类型检查器)。
-
在 Python 3.14 之前,旧式联合类型是通过私有类
typing._UnionGenericAlias
实现的。该类对于实现已不再需要,但为了向后兼容而保留,并计划在 Python 3.17 中移除。用户应使用文档化的内省辅助工具,如typing.get_origin()
和typing.get_args()
,而不是依赖于私有实现细节。typing.ByteString
,自 Python 3.9 起已弃用,计划在 Python 3.17 中移除。要测试
obj
是否在运行时实现了缓冲区协议,请使用isinstance(obj, collections.abc.Buffer)
。在类型注解中,请使用Buffer
或显式指定代码支持的类型的联合类型(例如bytes | bytearray | memoryview
)。ByteString
最初旨在作为bytes
和bytearray
的超类型。然而,由于 ABC 从未有任何方法,知道一个对象是ByteString
的实例实际上并不能告诉你任何关于该对象的有用信息。其他常见的缓冲区类型,如memoryview
,也从未被理解为ByteString
的子类型(无论是运行时还是静态类型检查器)。
计划在未来版本中移除¶
以下 API 将在未来移除,但目前尚未确定移除日期。
-
嵌套参数组和嵌套互斥组的做法已被弃用。
向
add_argument_group()
传递未写入文档的关键字参数 prefix_chars 的做法现已弃用。argparse.FileType
类型转换器已被弃用。
-
生成器:
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
的严格子类的实例。对
__complex__()
方法返回complex
的严格子类的支持:这些方法将被要求返回complex
的实例。将
int()
委托给__trunc__()
方法的做法。在
complex()
构造函数中将复数作为 real 或 imag 参数传递的做法现已弃用;它应该仅作为单个位置参数传递。(由 Serhiy Storchaka 在 gh-109218 中贡献。)
calendar
:calendar.January
和calendar.February
常量已弃用,并由calendar.JANUARY
和calendar.FEBRUARY
替换。(由 Prince Roshan 在 gh-103636 贡献)。codecs
:请使用open()
而不是codecs.open()
。(gh-133038)-
utcnow()
:请使用datetime.datetime.now(tz=datetime.UTC)
。utcfromtimestamp()
:请使用datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)
。
gettext
:复数值必须是整数。-
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
选项和协议不带协议参数的
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
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()
。
内部类
typing._UnionGenericAlias
不再用于实现typing.Union
。为了保持与使用此私有类的用户的兼容性,将提供一个兼容性垫片,至少持续到 Python 3.17。(由 Jelle Zijlstra 在 gh-105499 中贡献。)unittest.IsolatedAsyncioTestCase
:从测试用例返回非None
的值已被弃用。urllib.parse
中已弃用的函数:请改用urlparse()
splitattr()
splithost()
splitnport()
splitpasswd()
splitport()
splitquery()
splittag()
splittype()
splituser()
splitvalue()
to_bytes()
wsgiref
:SimpleHandler.stdout.write()
不应进行部分写入。xml.etree.ElementTree
:测试Element
的真值的做法已被弃用。在未来的版本中,它将始终返回True
。请优先使用显式的len(elem)
或elem is not None
测试。sys._clear_type_cache()
已被弃用:请改用sys._clear_internal_caches()
。
已移除¶
asynchat 和 asyncore¶
configparser¶
configparser
中自 3.2 以来弃用的一些名称已根据 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
-based (和distutils
-based) 包仍然可以通过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¶
ssl¶
移除
ssl
的ssl.RAND_pseudo_bytes()
函数,它在 Python 3.6 中已弃用:请改用os.urandom()
或ssl.RAND_bytes()
。(由 Victor Stinner 在 gh-94199 中贡献。)移除
ssl.match_hostname()
函数。它在 Python 3.7 中已弃用。OpenSSL 自 Python 3.7 起执行主机名匹配,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 以及 Firefox 35 及以下版本(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 中贡献。)移除几个标准库模块和测试中
Jython
兼容性补丁。(由 Nikita Sobolev 在 gh-99482 中贡献。)从
ctypes
模块中移除_use_broken_old_ctypes_structure_semantics_
标志。(由 Nikita Sobolev 在 gh-99285 中贡献。)
移植到 Python 3.12¶
本节列出了前面描述过的变更以及其他可能需要修改代码的 bug 修复。
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 中描述的令牌:FSTRING_START
、FSTRING_MIDDLE
和FSTRING_END
现在除了表达式组件中分词的适当令牌外,还为 f-字符串“字符串”部分发出。例如,对于 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
变量,以在make install
中覆盖compileall
选项(默认值:-j0
)。还将 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 中贡献。)向 C API 添加新函数
PyFunction_SetVectorcall()
,它设置给定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_BUILD_CORE
一起使用时,这现在会将引用计数初始化为_Py_IMMORTAL_REFCNT
。
SSTATE_INTERNED_IMMORTAL
已intern unicode 对象的标识符是不朽的。
SSTATE_INTERNED_IMMORTAL_STATIC
已intern unicode 对象的标识符是不朽且静态的
sys.getunicodeinternedsize
这返回已intern的 unicode 对象的总数已intern。现在需要它才能使
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 中贡献。PEP 作者 Ken Jin。)弃用全局配置变量
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 中贡献。)structmember.h
头文件已弃用,尽管它仍然可用,并且没有计划将其移除。现在只需包含
Python.h
,其内容即可使用,如果缺少,则会添加Py
前缀类型宏,如
Py_T_INT
、Py_T_DOUBLE
等(以前是T_INT
、T_DOUBLE
等)标志
Py_READONLY
(以前是READONLY
)和Py_AUDIT_READ
(以前全是大写)
有几项未从
Python.h
中公开T_OBJECT
(使用Py_T_OBJECT_EX
)T_NONE
(以前未文档化,而且相当古怪)宏
WRITE_RESTRICTED
,它什么也不做。宏
RESTRICTED
和READ_RESTRICTED
,它们与Py_AUDIT_READ
等效。在某些配置中,
<stddef.h>
未包含在Python.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 3.15 中移除¶
PyWeakref_GetObject()
和PyWeakref_GET_OBJECT()
:请改用PyWeakref_GetRef()
。可以使用 pythoncapi-compat 项目 在 Python 3.12 及更早版本上获取PyWeakref_GetRef()
。Py_UNICODE
类型和Py_UNICODE_WIDE
宏:请改用wchar_t
。PyUnicode_AsDecodedObject()
:请改用PyCodec_Decode()
。PyUnicode_AsDecodedUnicode()
:请改用PyCodec_Decode()
;请注意,某些编解码器(例如“base64”)可能返回str
以外的类型,例如bytes
。PyUnicode_AsEncodedObject()
:请改用PyCodec_Encode()
。PyUnicode_AsEncodedUnicode()
:请改用PyCodec_Encode()
;请注意,某些编解码器(例如“base64”)可能返回bytes
以外的类型,例如str
。Python 初始化函数,在 Python 3.13 中被弃用
Py_GetPath()
:请改用PyConfig_Get("module_search_paths")
(sys.path
)。Py_GetPrefix()
:请改用PyConfig_Get("base_prefix")
(sys.base_prefix
)。如果需要处理 虚拟环境,请使用PyConfig_Get("prefix")
(sys.prefix
)。Py_GetExecPrefix()
:请改用PyConfig_Get("base_exec_prefix")
(sys.base_exec_prefix
)。如果需要处理 虚拟环境,请使用PyConfig_Get("exec_prefix")
(sys.exec_prefix
)。Py_GetProgramFullPath()
:请改用PyConfig_Get("executable")
(sys.executable
)。Py_GetProgramName()
:请改用PyConfig_Get("executable")
(sys.executable
)。Py_GetPythonHome()
:请改用PyConfig_Get("home")
或PYTHONHOME
环境变量。
可以使用 pythoncapi-compat 项目 在 Python 3.13 及更早版本中获得
PyConfig_Get()
。用于配置 Python 初始化的函数,在 Python 3.11 中被弃用
PySys_SetArgvEx()
:请改用设置PyConfig.argv
。PySys_SetArgv()
:请改用设置PyConfig.argv
。Py_SetProgramName()
:请改用设置PyConfig.program_name
。Py_SetPythonHome()
:请改用设置PyConfig.home
。PySys_ResetWarnOptions()
:请改用清空sys.warnoptions
和warnings.filters
。
应使用
Py_InitializeFromConfig()
API 与PyConfig
配合使用。全局配置变量
Py_DebugFlag
:请改用PyConfig.parser_debug
或PyConfig_Get("parser_debug")
。Py_VerboseFlag
:请改用PyConfig.verbose
或PyConfig_Get("verbose")
。Py_InteractiveFlag
:请改用PyConfig.interactive
或PyConfig_Get("interactive")
。Py_InspectFlag
:请改用PyConfig.inspect
或PyConfig_Get("inspect")
。Py_OptimizeFlag
:请改用PyConfig.optimization_level
或PyConfig_Get("optimization_level")
。Py_NoSiteFlag
:请改用PyConfig.site_import
或PyConfig_Get("site_import")
。Py_BytesWarningFlag
:请改用PyConfig.bytes_warning
或PyConfig_Get("bytes_warning")
。Py_FrozenFlag
:请改用PyConfig.pathconfig_warnings
或PyConfig_Get("pathconfig_warnings")
。Py_IgnoreEnvironmentFlag
:请改用PyConfig.use_environment
或PyConfig_Get("use_environment")
。Py_DontWriteBytecodeFlag
:请改用PyConfig.write_bytecode
或PyConfig_Get("write_bytecode")
。Py_NoUserSiteDirectory
:请改用PyConfig.user_site_directory
或PyConfig_Get("user_site_directory")
。Py_UnbufferedStdioFlag
:请改用PyConfig.buffered_stdio
或PyConfig_Get("buffered_stdio")
。Py_HashRandomizationFlag
:请改用PyConfig.use_hash_seed
和PyConfig.hash_seed
或PyConfig_Get("hash_seed")
。Py_IsolatedFlag
:请改用PyConfig.isolated
或PyConfig_Get("isolated")
。Py_LegacyWindowsFSEncodingFlag
:请改用PyPreConfig.legacy_windows_fs_encoding
或PyConfig_Get("legacy_windows_fs_encoding")
。Py_LegacyWindowsStdioFlag
:请改用PyConfig.legacy_windows_stdio
或PyConfig_Get("legacy_windows_stdio")
。Py_FileSystemDefaultEncoding
、Py_HasFileSystemDefaultEncoding
:请改用PyConfig.filesystem_encoding
或PyConfig_Get("filesystem_encoding")
。Py_FileSystemDefaultEncodeErrors
:请改用PyConfig.filesystem_errors
或PyConfig_Get("filesystem_errors")
。Py_UTF8Mode
:请改用PyPreConfig.utf8_mode
或PyConfig_Get("utf8_mode")
。(请参阅Py_PreInitialize()
)
应使用
Py_InitializeFromConfig()
API 与PyConfig
一起设置这些选项。或者,可以使用PyConfig_Get()
在运行时获取这些选项。
预计在 Python 3.16 中移除¶
捆绑的
libmpdec
副本。
预计在未来版本中移除¶
以下 API 已被弃用并将被移除,但目前尚未确定移除日期。
Py_TPFLAGS_HAVE_FINALIZE
:自 Python 3.8 起已不再需要。PySlice_GetIndicesEx()
:请改用PySlice_Unpack()
和PySlice_AdjustIndices()
。PyUnicode_READY()
:自 Python 3.12 起已不再需要PyErr_Display()
:请改用PyErr_DisplayException()
。_PyErr_ChainExceptions()
:请改用_PyErr_ChainExceptions1()
。PyBytesObject.ob_shash
成员:请改用调用PyObject_Hash()
。线程本地存储 (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 中贡献。)