本文介绍了 Python 3.11 与 3.10 相比的新功能。
有关完整详细信息,请参阅更改日志。
发布亮点
- Python 3.11 比 Python 3.10 快 10-60%。平均而言,我们测量了标准基准套件的 1.25 倍加速。有关详细信息,请参阅更快的 CPython。
新的语法特性:
- PEP 654:异常组和
except*
.
新的内置功能:
- PEP 678:使用注释丰富异常。
新的标准库模块:
- PEP 680 :
tomllib
— 支持在标准库中解析 TOML。
解释器改进:
-
PEP 657:在回溯中包含细粒度的错误位置。
-
新的
-P
命令行选项和PYTHONSAFEPATH
环境变量以禁用自动将潜在不安全路径(工作目录或脚本目录,取决于调用)添加到sys.path
.
类型相关的新功能:
-
PEP 646:可变参数泛型。
-
PEP 655:将单个 TypedDict 项目标记为需要或可能丢失。
-
PEP 673:
Self
类型。 -
PEP 675:任意文字字符串类型。
-
PEP 681:数据类转换。
重要的弃用、删除或限制:
新功能
PEP 657:回溯中增强的错误位置
打印回溯时,解释器现在将指向导致错误的确切表达式,而不仅仅是行。例如:
Traceback (most recent call last):
File "distance.py", line 11, in <module>
print(manhattan_distance(p1, p2))
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "distance.py", line 6, in manhattan_distance
return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'
以前版本的解释器只会指向该行,从而使对象是None
. dict
在处理深度嵌套的对象和多个函数调用时,这些增强的错误也很有帮助:
Traceback (most recent call last):
File "query.py", line 37, in <module>
magic_arithmetic('foo')
File "query.py", line 18, in magic_arithmetic
return add_counts(x) / 25
^^^^^^^^^^^^^
File "query.py", line 24, in add_counts
return 25 + query_user(user1) + query_user(user2)
^^^^^^^^^^^^^^^^^
File "query.py", line 32, in query_user
return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
~~~~~~~~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable
以及复杂的算术表达式:
Traceback (most recent call last):
File "calculation.py", line 54, in <module>
result = (x / y / z) * (a / b / c)
~~~~~~^~~
ZeroDivisionError: division by zero
此外,增强回溯功能使用的信息可通过通用 API 获得,可用于将 字节码 指令与源代码位置相关联。可以使用以下方法检索此信息:
-
Python中的
codeobject.co_positions()
方法。 -
C API 中的
PyCode_Addr2Location()
函数。
看PEP 657了解更多详情。(由 Pablo Galindo、Batuhan Taskaya 和 Ammar Askar 在bpo-43950中贡献。)
PEP 654:异常组和except*
PEP 654引入了语言特性,使程序能够同时引发和处理多个不相关的异常。内置类型ExceptionGroup
并BaseExceptionGroup
可以将异常分组并将它们一起引发,并且新except*
语法可以泛化 except
以匹配异常组的子组。
看PEP 654了解更多详情。
(由 Irit Katriel 在bpo-45292中贡献。PEP由 Irit Katriel、Yury Selivanov 和 Guido van Rossum 编写。)
PEP 678:可以用注释来丰富异常
该add_note()
方法被添加到BaseException
. 它可用于使用在引发异常时不可用的上下文信息来丰富异常。添加的注释出现在默认回溯中。
看PEP 678了解更多详情。
(由 Irit Katriel 在bpo-45607中提供。PEP由 Zac Hatfield-Dodds 编写。)
其他语言变化
-
现在允许在异步函数的推导中使用异步推导。外部理解隐含地变为异步的。(由 Serhiy Storchaka 在bpo-33346中贡献。)
-
TypeError
现在引发了A而不是AttributeError
incontextlib.ExitStack.enter_context()
和contextlib.AsyncExitStack.enter_async_context()
for 相应的不支持上下文管理器或异步上下文管理器 协议的对象。(由 Serhiy Storchaka 在bpo-44471中贡献。) -
对于不支持上下文管理器或异步上下文管理器 协议的对象,现在提出了A
TypeError
而不是AttributeError
inwith
和语句。(由 Serhiy Storchaka 在bpo-12022中贡献。)async with
-
添加
object.__getstate__()
了它提供了该方法的默认实现__getstate__()
。Copying
和pickling
内置类型的子类的实例bytearray
,set
,frozenset
,collections.OrderedDict
,collections.deque
,weakref.WeakSet
和datetime.tzinfo
现在复制和腌制实例属性实现为slot。(由 Serhiy Storchaka 在bpo-26579中贡献。) -
添加
-P
命令行选项和PYTHONSAFEPATH
环境变量不预先添加潜在的不安全路径,sys.path
例如当前目录、脚本目录或空字符串。(由 Victor Stinner 在gh-57684中提供。) -
向格式规范迷你语言添加了一个
"z"
选项,该选项在舍入到格式精度后将负零强制为零。看 PEP 682了解更多详情。(由 John Belmonte 在gh-90153中提供。) -
上不再接受字节
sys.path
。在 Python 3.2 和 3.6 之间的某个时候支持中断,直到 Python 3.10.0 发布之后才有人注意到。-b
由于字符串和字节键之间的交互以及sys.path_importer_cache
何时混合使用,恢复支持也会有问题。(由 Thomas Grainger 在gh-91181中提供。)
其他 CPython 实现更改
-
特殊方法
complex.__complex__()
和bytes.__bytes__()
实现支持typing.SupportsComplex
和typing.SupportsBytes
协议。(由 Mark Dickinson 和 Dong-hee Na 在bpo-24234中贡献。) -
siphash13
被添加为新的内部散列算法。它具有类似的安全属性,siphash24
但对于长输入来说速度稍快。str
,bytes
和其他一些类型现在使用它作为hash()
.PEP 552 基于散列的 pyc 文件现在siphash13
也使用 . (由 Inada Naoki 在bpo-29410中贡献。) -
当不带参数的语句重新引发活动异常时
raise
,附加到此异常的回溯现在始终为sys.exc_info()[1].__traceback__
. 这意味着对当前except
子句中的回溯所做的更改会反映在重新引发的异常中。(由 Irit Katriel 在bpo-45711中贡献。) -
解释器状态表示的已处理异常(又名 exc_info 或 _PyErr_StackItem)现在只有该
exc_value
字段,exc_type
并且exc_traceback
已被删除,因为它们的值可以从exc_value
. (由 Irit Katriel 在bpo-45711中贡献。) -
为 Windows 安装程序
AppendPath
添加了一个新的命令行选项。它的行为类似于PrependPath
但附加了 install 和 scripts 目录,而不是预先添加它们。(由 Bastian Neuburger 在bpo-44934中贡献。) -
该
PyConfig.module_search_paths_set
字段现在必须设置为 1 才能用于PyConfig.module_search_paths
初始化sys.path
。否则,初始化将重新计算路径并替换添加到module_search_paths
. -
该
--help
选项的输出更改为适合 50 行和 80 列。有关Python 环境变量的信息 ,可通过 new或 标志和. (由 Éric Araujo 在bpo-46142中贡献。)-X options
--help-env
--help-xoptions
--help-all
-
在 2(二进制)、4、8(八进制)、16(十六进制)或 32(如以 10(十进制)为基数)以外的基数之间进行转换现在会引发 a
int
如果字符串形式的位数超过避免的限制由于算法复杂性,潜在的拒绝服务攻击。这是针对CVE-2020-10735的缓解措施。可以通过环境变量、命令行标志或API 配置或禁用此限制。请参阅整数字符串转换长度限制文档。默认限制为字符串形式的 4300 位数字。str
ValueError
sys
新模块
-
添加了一个新模块,
tomllib
用于解析 TOML。(由 Taneli Hukkinen 在bpo-40059中贡献。) -
wsgiref.types
,包含用于静态类型检查的特定于 WSGI 的类型,已添加。(由 Sebastian Rittau 在bpo-42012中贡献。)
改进的模块
asyncio
-
将原始数据报套接字函数添加到事件循环
sock_sendto()
:sock_recvfrom()
和sock_recvfrom_into()
. (由 Alex Grönholm 在bpo-46805中贡献。) -
添加
start_tls()
将现有的基于流的连接升级到 TLS 的方法。(由 Ian Good 在 bpo-34975中贡献。) -
将
Barrier
类添加到 asyncio 库的同步原语中。(由 Yves Duprat 和 Andrew Svetlov 在 gh-87518中提供。) -
添加
TaskGroup
类,一个异步上下文管理器 ,其中包含一组任务,这些任务将在退出时等待所有任务。(由 Yury Seliganov 等人提供。)
contextlib
添加了非并行安全chdir()
上下文管理器以更改当前工作目录,然后在退出时恢复它。简单的包装chdir()
。(由 Filipe Laíns 在bpo-25625中贡献)
dataclasses
datetime
-
添加
datetime.UTC
, 的方便别名datetime.timezone.utc
。(由 Kabir Kwatra 在gh-91973中提供。) -
datetime.date.fromisoformat()
,datetime.time.fromisoformat()
现在datetime.datetime.fromisoformat()
可用于解析大多数 ISO 8601 格式(仅支持小数小时和分钟的格式除外)。(由 Paul Ganssle 在gh-80010中提供。)
enum
-
EnumMeta
重命名为EnumType
(EnumMeta
保留为别名)。 -
StrEnum
添加——枚举成员是并且必须是字符串。 -
ReprEnum
添加 - 仅导致__repr__
被修改,而不是__str__
或__format__
。 -
FlagBoundary
添加 - 控制为标志提供无效值时的行为。 -
EnumCheck
添加 - 用于verify
确保各种约束。 -
verify
添加了 – 确保给定EnumCheck
约束的功能。 -
member
添加 - 装饰器以确保将给定对象转换为枚举成员。 -
nonmember
添加 - 装饰器以确保给定对象不会转换为枚举成员。 -
property
添加 - 使用而不是types.DynamicClassAttribute
. -
global_enum
添加了——枚举装饰器来调整__repr__
和__str__
显示全局上下文中的成员——参见re.RegexFlag
示例。 -
Flag
增强:成员支持长度、迭代和包含检查。 -
Enum
/Flag
修复:成员现在被定义之前__init_subclass__
被调用;dir()
现在包括来自混合数据类型的方法等。 -
Flag
修复:只有主值(2 的幂)被认为是规范的,而复合值(3、6、10 等)被认为是别名;倒置标志被强制转换为正等值。 -
IntEnum
//修复IntFlag
:StrEnum
这些现在继承自,ReprEnum
因此str()
输出现在匹配format()
输出,即数据类型(所以两者str(AnIntEnum.ONE)
都format(AnIntEnum.ONE)
等于'1'
)。
fractions
-
支持PEP 515
Fraction
-从字符串初始化(由 Sergey B Kirpichev 在bpo-44258中贡献。) -
Fraction
现在实现一个__int__
方法,以便检查通过。(由 Mark Dickinson 在bpo-44547中贡献。)isinstance(some_fraction, typing.SupportsInt)
functools
-
functools.singledispatch()
现在支持types.UnionType
和typing.Union
作为 dispatch 参数的注解。:>>>
>>> from functools import singledispatch >>> @singledispatch ... def fun(arg, verbose=False): ... if verbose: ... print("Let me just say,", end=" ") ... print(arg) ... >>> @fun.register ... def _(arg: int | float, verbose=False): ... if verbose: ... print("Strength in numbers, eh?", end=" ") ... print(arg) ... >>> from typing import Union >>> @fun.register ... def _(arg: Union[list, set], verbose=False): ... if verbose: ... print("Enumerate this:") ... for i, elem in enumerate(arg): ... print(i, elem) ...
(由 Yurii Karabas 在bpo-46014中贡献。)
hashlib
-
hashlib.blake2b()
hashlib.blake2s()
现在更喜欢libb2而 不是 Python 的 vendored 副本。(由 Christian Heimes 在bpo-47095中贡献。) -
带有 SHA3 和 SHAKE 算法的内部
_sha3
模块现在使用 _tiny_sha3_而不是_Keccak 代码包_来减少代码和二进制大小。该hashlib
模块更喜欢 OpenSSL 的优化 SHA3 和 SHAKE 实现。此更改仅影响不支持 OpenSSL 的安装。(由 Christian Heimes 在bpo-47098中贡献。) -
Add
hashlib.file_digest()
,一个用于有效散列文件或类似文件的对象的辅助函数。(由 Christian Heimes 在gh-89313中提供。)
空闲和空闲库
-
对.pyi文件应用语法高亮。(由 Alex Waygood 和 Terry Jan Reedy 在bpo-45447中贡献。)
-
在保存带有输入和输出的 Shell 时包括提示。(由 Terry Jan Reedy 在gh-95191中提供。)
inspect
-
添加
inspect.getmembers_static()
:返回所有成员,而不通过描述符协议触发动态查找。(由洪伟鹏在bpo-30533中贡献。) -
添加
inspect.ismethodwrapper()
用于检查对象的类型是否为MethodWrapperType
. (由 Hakan Çelik 在bpo-29418中贡献。) -
更改模块中与帧相关的函数
inspect
以返回包含扩展的常规对象(向后兼容旧的类元组接口)PEP 657位置信息(结束行号、列和结束列)。受影响的函数是:inspect.getframeinfo()
、inspect.getouterframes()
、inspect.getinnerframes()
和 。(由 Pablo Galindo 在 gh-88116中提供。)inspect.stack()
inspect.trace()
locale
- 添加
locale.getencoding()
以获取当前的语言环境编码。它类似于locale.getpreferredencoding(False)
但忽略了 Python UTF-8 Mode。
math
-
加
math.exp2()
:返回 2 的 x 次方。(由 Gideon Mitchell 在bpo-45917中贡献。) -
添加
math.cbrt()
:返回 x 的立方根。(由 Ajith Ramachandran 在bpo-44357中贡献。) -
math.pow()
为了与 IEEE 754 规范保持一致,更改了两个极端情况的行为。操作 ,现在返回 。以前他们提出了. (由 Mark Dickinson 在bpo-44339中贡献。)math.pow(0.0, -math.inf)``math.pow(-0.0, -math.inf)``inf
ValueError
operator
- 添加了一个新功能
operator.call
,例如 . (由 Antony Lee 在bpo-44019中贡献。)operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)
os
- 在 Windows 上,
os.urandom()
现在使用BCryptGenRandom()
,而不是CryptGenRandom()
已弃用。(由 Dong-hee Na 在bpo-44611中提供。)
pathlib
re
- 正则表达式现在支持原子分组 (
(?>...)
) 和所有格量词 (*+
,++
,?+
, )。{m,n}+
(由 Jeffrey C. Jacobs 和 Serhiy Storchaka 在bpo-433030中贡献。)
shutil
- 添加可选参数_dir_fd_在
shutil.rmtree()
. (由 Serhiy Storchaka 在bpo-46245中贡献。)
socket
-
添加对 NetBSD 的 CAN Socket 支持。(由 Thomas Klausner 在bpo-30512中贡献。)
-
create_connection()
如果连接失败,可以选择引发一个ExceptionGroup
包含所有错误的选项,而不是只引发最后一个错误。(由 Irit Katriel 在bpo-29980中贡献。)
sqlite3
-
您现在可以通过传递
None
给 来 禁用授权者set_authorizer()
。(由 Erlend E. Aasland 在bpo-44491中贡献。) -
排序规则名称
create_collation()
现在可以包含任何 Unicode 字符。带有无效字符的排序规则名称现在提升UnicodeEncodeError
而不是sqlite3.ProgrammingError
. (由 Erlend E. Aasland 在bpo-44688中贡献。) -
sqlite3
例外现在包括 SQLite 扩展错误代码 assqlite_errorcode
和 SQLite 错误名称 assqlite_errorname
。(由 Aviv Palivoda、Daniel Shahaf 和 Erlend E. Aasland 在 bpo-16379和bpo-24139 中贡献。) -
添加
setlimit()
和getlimit()
用于sqlite3.Connection
按连接基础设置和获取 SQLite 限制。(由 Erlend E. Aasland 在bpo-45243中贡献。) -
sqlite3
现在sqlite3.threadsafety
基于编译底层 SQLite 库的默认线程模式设置。(由 Erlend E. Aasland 在bpo-45613中贡献。) -
sqlite3
如果启用了回调回溯,C 回调现在使用不可引发的异常。用户现在可以注册一个 来改善他们的调试体验。(由 Erlend E. Aasland 在bpo-45828中贡献。)unraisable hook handler
-
跨回滚获取不再引发
InterfaceError
。相反,我们将其留给 SQLite 库来处理这些情况。(由 Erlend E. Aasland 在bpo-44092中贡献。) -
Add
serialize()
anddeserialize()
tosqlite3.Connection
用于序列化和反序列化数据库。(由 Erlend E. Aasland 在bpo-41930中贡献。) -
添加
create_window_function()
到sqlite3.Connection
用于创建聚合窗口函数。(由 Erlend E. Aasland 在bpo-34916中贡献。) -
添加
blobopen()
到sqlite3.Connection
.sqlite3.Blob
允许对 blob 进行增量 I/O 操作。(由 Aviv Palivoda 和 Erlend E. Aasland 在bpo-24905中贡献。)
sys
-
sys.exc_info()
现在从(异常实例)派生type
andtraceback
字段value
,因此当异常在处理过程中被修改时,更改会反映在对 . 的后续调用的结果中exc_info()
。(由 Irit Katriel 在bpo-45711中贡献。) -
添加
sys.exception()
返回活动异常实例(相当于sys.exc_info()[1]
)。(由 Irit Katriel 在bpo-46328中贡献。) -
添加
sys.flags.safe_path
标志。(由 Victor Stinner 在gh-57684中提供。)
sysconfig
- 添加了三个新的安装方案 (posix_venv、nt_venv_和_venv),并在 Python 创建新的虚拟环境或从虚拟环境运行时使用。前两个方案(posix_venv_和_nt_venv)是针对非 Windows 和 Windows的操作系统,根据 Python 运行的操作系统, _venv本质上是其中一个的别名。_这对于修改
sysconfig.get_preferred_scheme()
. 创建新虚拟环境的第三方代码应该使用新的 _venv_安装方案来确定路径,就像venv
. (由 Miro Hrončok 在bpo-45413中贡献.)
threading
- 在 Unix 上,如果该
sem_clockwait()
函数在 C 库(glibc 2.30 和更高版本)中可用,则该threading.Lock.acquire()
方法现在使用单调时钟 (time.CLOCK_MONOTONIC
) 进行超时,而不是使用系统时钟 (time.CLOCK_REALTIME
),以不受系统时钟更改的影响。(由 Victor Stinner 在bpo-41710中贡献。)
time
-
在 Unix 上,
time.sleep()
现在使用clock_nanosleep()
ornanosleep()
函数(如果可用),其分辨率为 1 纳秒(10 -9秒),而不是使用select()
其分辨率为 1 微秒(10 -6秒)。(由 Benjamin Szőke 和 Victor Stinner 在bpo-21302中贡献。) -
在 Windows 8.1 和更新版本上,
time.sleep()
现在使用基于高分辨率计时器的可等待计时器 ,其分辨率为 100 纳秒(10 -7秒)。以前,它的分辨率为 1 毫秒(10 -3秒)。(由 Benjamin Szőke、Dong-hee Na、Eryk Sun 和 Victor Stinner 在bpo-21302和bpo-45429 中贡献。)
traceback
-
添加
traceback.StackSummary.format_frame_summary()
以允许用户覆盖哪些帧出现在回溯中,以及它们的格式。(由 Ammar Askar 在bpo-44569中贡献。) -
Add
traceback.TracebackException.print()
,它将格式化的TracebackException
实例打印到文件中。(由 Irit Katriel 在bpo-33809中贡献。)
typing
有关重大更改,请参阅与类型提示相关的新功能。
-
添加
typing.assert_never()
和typing.Never
。typing.assert_never()
对于要求类型检查器确认无法访问某行代码很有用。在运行时,它会引发一个AssertionError
. (由 Jelle Zijlstra 在gh-90633中提供。) -
添加
typing.reveal_type()
. 这对于询问类型检查器它为给定表达式推断出的类型很有用。在运行时,它会打印接收到的值的类型。(由 Jelle Zijlstra 在gh-90572中提供。) -
添加
typing.assert_type()
. 这对于要求类型检查器确认它为给定表达式推断的类型是否与给定类型匹配很有用。在运行时,它只是返回接收到的值。(由 Jelle Zijlstra 在gh-90638中提供。) -
typing.TypedDict
类型现在可以是通用的。(由 Samodya Abeysiriwardane 在gh-89026中提供。) -
NamedTuple
类型现在可以是通用的。(由 Serhiy Storchaka 在bpo-43923中贡献。) -
允许子类化
typing.Any
. 这对于避免与高度动态类相关的类型检查器错误很有用,例如模拟。(由 Shantanu Jain 在gh-91154中提供。) -
typing.final()
装饰器现在设置被装饰对象的属性__final__
。(由 Jelle Zijlstra 在gh-90500中提供。) -
该
typing.get_overloads()
函数可用于内省函数的重载。typing.clear_overloads()
可用于清除函数的所有已注册重载。(由 Jelle Zijlstra 在gh-89263中提供。) -
现在保留了子类的
__init__()
方法。Protocol
(由 Adrian Garcia Badarasco 在gh-88970中提供。) -
空元组类型 (
Tuple[()]
) 的表示被简化了。这会影响内省,例如get_args(Tuple[()])
现在评估为()
而不是((),)
. (由 Serhiy Storchaka 在gh-91137中提供。) -
typing._type_check
通过删除私有函数中的可调用检查来放松类型注释的运行时要求。(由 Gregory Beauregard 在gh-90802中提供。) -
typing.get_type_hints()
现在支持将字符串评估为PEP 585 通用别名中的前向引用。(由 Niklas Rosenstein 在gh-85542中提供。) -
typing.get_type_hints()
不再默认添加Optional
到参数中。None
(由 Nikita Sobolev 在gh-90353中提供。) -
typing.get_type_hints()
现在支持评估裸字符串化ClassVar
注释。(由 Gregory Beauregard 在gh-90711中提供。) -
typing.no_type_check()
不再修改外部类和函数。它现在还正确地将类方法标记为不进行类型检查。(由 Nikita Sobolev 在gh-90729中提供。)
tkinter
- 添加
info_patchlevel()
了将 Tcl 库的确切版本作为命名元组返回的方法,类似于sys.version_info
. (由 Serhiy Storchaka 在gh-91827中提供。)
unicodedata
- Unicode 数据库已更新至版本 14.0.0。(由 Benjamin Peterson 在bpo-45190中贡献)。
unittest
- 添加了类的方法
enterContext()
和enterClassContext()
类TestCase
,enterAsyncContext()
类的方法IsolatedAsyncioTestCase
和函数unittest.enterModuleContext()
。(由 Serhiy Storchaka 在bpo-45046中贡献。)
venv
- 创建新的 Python 虚拟环境时,使用_venv_ sysconfig 安装方案来确定环境内部的路径。Python在虚拟环境中运行时,默认安装方案相同。这意味着下游分销商可以在不改变虚拟环境行为的情况下更改默认的 sysconfig 安装方案。也创建新虚拟环境的第三方代码也应该这样做。(由 Miro Hrončok 在bpo-45413中贡献。)
warnings
warnings.catch_warnings()
现在接受 的参数warnings.simplefilter()
,提供一种更简洁的方式来本地忽略警告或将它们转换为错误。(由 Zac Hatfield-Dodds 在bpo-47074中贡献。)
zipfile
- 添加了对指定成员名称编码以读取 zipfile 目录和文件头中的元数据的支持。(由 Stephen J. Turnbull 和 Serhiy Storchaka 在bpo-28080中贡献。)
fcntl
- 在 FreeBSD 上,
F_DUP2FD
和F_DUP2FD_CLOEXEC
flags 分别被支持,前者相当于dup2
使用,后者FD_CLOEXEC
额外设置了 flag。
Optimizations
-
编译器现在使用仅包含格式代码的文字格式优化简单的 C 样式格式
%s
,%r
并%a
使其与相应的 f 字符串表达式一样快。(由 Serhiy Storchaka 在bpo-28307中贡献。) -
实施“零成本”例外。
try
当不引发异常时,语句的成本几乎可以消除。(由 Mark Shannon 在bpo-40222中贡献。) -
纯 ASCII 字符串现在在常数时间内通过
unicodedata.normalize()
. (由 Dong-hee Na 在bpo-44987中提供。) -
math
函数comb()
,perm()
现在对于大参数来说速度提高了 10 倍或更多(对于较大的_k_速度更快)。(由 Serhiy Storchaka 在bpo-37295中贡献。) -
当所有插入的键都是 Unicode 对象时,字典不存储哈希值。这减少了字典大小。例如,
sys.getsizeof(dict.fromkeys("abcdefg"))
在 64 位平台上从 352 字节变为 272 字节。(由 Inada Naoki 在bpo-46845中贡献。) -
re
的正则表达式匹配引擎已部分重构,现在在支持的平台上使用计算的 goto(或“线程代码”)。因此,Python 3.11 执行pyperformance 正则表达式基准的速度比 Python 3.10 快 10%。
更快的 CPython
当使用pyperformance基准套件测量并在 Ubuntu Linux 上使用 GCC 编译时, CPython 3.11 平均 比 CPython 3.10 快 25% 。根据您的工作量,加速可能会快 10-60%。
该项目专注于 Python 的两个主要领域:更快的启动和更快的运行时。不在此项目下的其他优化在优化中列出。
更快的启动
冻结导入/静态代码对象
Python 在__pycache__目录中缓存字节码以加速模块加载。
在 3.10 之前的版本中,Python 模块执行如下所示:
Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate
在 Python 3.11 中,Python 启动所必需的核心模块被“冻结”了。这意味着它们的代码对象(和字节码)是由解释器静态分配的。这将模块执行过程中的步骤减少到:
Statically allocated code object -> Evaluate
在 Python 3.11 中,解释器的启动速度现在提高了 10-15%。这对使用 Python 的短期运行程序有很大的影响。
(由 Eric Snow、Guido van Rossum 和 Kumar Aditya 在多个问题中提供。)
更快的运行时间
更便宜、更懒的 Python 框架
每当 Python 调用 Python 函数时,都会创建 Python 帧。该帧保存执行信息。以下是新的帧优化:
-
简化了框架创建过程。
-
通过大量重用 C 堆栈上的帧空间来避免内存分配。
-
简化了内部框架结构以仅包含基本信息。以前的帧包含额外的调试和内存管理信息。
旧式框架对象现在仅在调试器或 Python 自省函数(如sys._getframe
或 )请求时创建inspect.currentframe
。对于大多数用户代码,根本不会创建框架对象。结果,几乎所有 Python 函数调用都显着加快了速度。我们测量了 3-7% 的 pyperformance 加速。
(由 Mark Shannon 在bpo-44590中贡献。)
内联 Python 函数调用
在 Python 函数调用期间,Python 将调用评估 C 函数来解释该函数的代码。这有效地将纯 Python 递归限制在对 C 堆栈安全的范围内。
在 3.11 中,当 CPython 检测到 Python 代码调用另一个 Python 函数时,它会设置一个新框架,并“跳转”到新框架内的新代码。这完全避免了调用 C 解释函数。
大多数 Python 函数调用现在不消耗 C 堆栈空间。这加快了大多数此类呼叫。在像斐波那契或阶乘这样的简单递归函数中,观察到了 1.7 倍的加速。这也意味着递归函数可以递归得更深(如果用户增加递归限制)。我们测量了 pyperformance 提高了 1-3%。
(由 Pablo Galindo 和 Mark Shannon 在bpo-45256中贡献。)
PEP 659:专门的自适应解释器
PEP 659是更快的 CPython 项目的关键部分之一。一般的想法是,虽然 Python 是一种动态语言,但大多数代码都有对象和类型很少更改的区域。这个概念被称为_类型稳定性_。
在运行时,Python 将尝试在执行代码中寻找常见模式和类型稳定性。然后,Python 将用更专业的操作替换当前操作。这种专门的操作使用仅适用于那些用例/类型的快速路径,这些用例/类型通常优于它们的通用对应物。这也带来了另一个称为_内联缓存_的概念,其中 Python 将昂贵操作的结果直接缓存在字节码中。
专门化者还将某些常用指令对组合成一个超指令。这减少了执行期间的开销。
Python 只有在看到“热”(多次执行)的代码时才会专门化。这可以防止 Python 将时间浪费在运行一次的代码上。当代码过于动态或用途发生变化时,Python 也可以去专门化。定期尝试专业化,并且专业化尝试不会太昂贵。这使专业化能够适应新的环境。
(由 Mark Shannon 撰写的 PEP,灵感来自 Stefan Brunthaler。见PEP 659了解更多信息。Mark Shannon 和 Brandt Bucher 在 Irit Katriel 和 Dennis Sweeney 的帮助下实施。)
操作 | 形式 | 详细描述 | 操作加速(最多) | 贡献者 |
---|---|---|---|---|
二元运算 | x+x; x*x; x-x; |
常见类型(例如 , int )的二进制加法、乘法和减法float ,并str 为其基础类型采用自定义快速路径。 |
10% | 马克·香农、娜东熙、布兰特·布彻、丹尼斯·斯威尼 |
下标 | a[i] |
下标容器类型,例如list , tuple 并dict 直接索引底层数据结构。下标自定义__getitem__ 也是内联的,类似于内联Python 函数调用。 |
10-25% | 伊瑞特·卡特里尔,马克·香农 |
存储下标 | a[i] = z |
类似于上面的下标专业化。 | 10-25% | 丹尼斯·斯威尼 |
来电 | f(arg) C(arg) |
len 调用常见的内置 © 函数和类型,例如str 直接调用其底层 C 版本。这避免了通过内部调用约定。 |
20% | 马克·香农、肯·金 |
加载全局变量 | print len |
globals/builtins 命名空间中的对象索引被缓存。加载全局变量和内置函数需要零命名空间查找。 | 1 | 马克香农 |
加载属性 | o.attr |
类似于加载全局变量。类/对象命名空间内的属性索引被缓存。在大多数情况下,属性加载将需要零命名空间查找。 | 2 | 马克香农 |
调用的加载方法 | o.meth() |
方法的实际地址被缓存。方法加载现在没有命名空间查找——即使对于具有长继承链的类也是如此。 | 10-20% | 金肯,马克·香农 |
店铺属性 | o.attr = z |
类似于负载属性优化。 | 2% 的性能 | 马克香农 |
解包序列 | *seq |
专门用于常见容器,例如list 和tuple 。避免内部调用约定。 |
8% | 布兰特·布赫 |
自 Python 3.8 以来已经存在类似的优化。3.11 专门针对更多形式并减少了一些开销。
自 Python 3.10 以来已经存在类似的优化。3.11 专门针对更多形式。此外,所有属性加载都应该由bpo-45947 加速。
Misc
-
由于延迟创建的对象命名空间,对象现在需要更少的内存。他们的命名空间字典现在也更自由地共享键。(在bpo-45340和bpo-40116中贡献了 Mark Shannon 。)
-
解释器中更简洁的异常表示将捕获异常所需的时间减少了约 10%。(由 Irit Katriel 在bpo-45711中贡献。)
FAQ
问:我应该如何编写代码来利用这些加速?
答:您不必更改代码。编写遵循常见最佳实践的 Pythonic 代码。Faster CPython 项目针对我们观察到的常见代码模式进行了优化。
问:CPython 3.11 会使用更多内存吗?
答:也许不是。我们预计内存使用不会超过 3.10 的 20%。如上所述,这被框架对象和对象字典的内存优化所抵消。
问:我的工作量没有任何加速。为什么?
答:某些代码不会有明显的好处。如果您的代码将大部分时间花在 I/O 操作上,或者已经在 numpy 之类的 C 扩展库中进行了大部分计算,则不会有显着的加速。该项目目前最有利于纯 Python 工作负载。
此外,pyperformance 数字是几何平均值。即使在 pyperformance 基准测试中,某些基准测试速度也略有下降,而其他基准测试速度则加快了近 2 倍!
问:有 JIT 编译器吗?
答:没有。我们仍在探索其他优化。
About
Faster CPython 探索了CPython的优化。主要团队由微软资助全职工作。Pablo Galindo Salgado 也得到了 Bloomberg LP 的资助,以兼职从事该项目。最后,许多贡献者是来自社区的志愿者。
CPython 字节码更改
-
字节码现在包含采用
CACHE
指令形式的内联缓存条目。许多操作码期望后跟确切数量的缓存,并指示解释器在运行时跳过它们。填充的缓存可能看起来像任意指令,因此在读取或修改包含加速数据的原始自适应字节码时应格外小心。 -
用单个 实现替换了所有数字
BINARY_*
和指令。INPLACE_*
BINARY_OP
-
将三个调用指令:
CALL_FUNCTION
和CALL_FUNCTION_KW
替换CALL_METHOD
为PUSH_NULL
、PRECALL
、CALL
和KW_NAMES
。这将方法的参数转移与关键字参数的处理分离,并允许更好地专门化调用。 -
删除
COPY_DICT_WITHOUT_KEYS
和GEN_START
。 -
MATCH_CLASS
并且MATCH_KEYS
不再推送一个额外的布尔值来指示匹配是成功还是失败。相反,它们指示失败None
(否则提取值的元组会出现)。 -
用 new 和指令替换几个堆栈操作指令(
DUP_TOP
、DUP_TOP_TWO
、ROT_TWO
、ROT_THREE
、ROT_FOUR
和) 。ROT_N
COPY
SWAP
-
替换
JUMP_IF_NOT_EXC_MATCH
为CHECK_EXC_MATCH
执行检查但不跳转。 -
替换
JUMP_IF_NOT_EG_MATCH
为CHECK_EG_MATCH
执行检查但不跳转。 -
换成
JUMP_ABSOLUTE
相对的JUMP_BACKWARD
。 -
已添加
JUMP_BACKWARD_NO_INTERRUPT
,用于不希望处理中断的某些循环中。 -
POP_JUMP_IF_TRUE
将and替换POP_JUMP_IF_FALSE
为相对POP_JUMP_FORWARD_IF_TRUE
的POP_JUMP_BACKWARD_IF_TRUE
,POP_JUMP_FORWARD_IF_FALSE
和POP_JUMP_BACKWARD_IF_FALSE
. -
添加
POP_JUMP_FORWARD_IF_NOT_NONE
、POP_JUMP_BACKWARD_IF_NOT_NONE
和 操作码POP_JUMP_FORWARD_IF_NONE
以POP_JUMP_BACKWARD_IF_NONE
加速条件跳转。 -
JUMP_IF_TRUE_OR_POP
JUMP_IF_FALSE_OR_POP
现在是相对的而不是绝对的。 -
RESUME
已添加。这是一个无操作。执行内部跟踪、调试和优化检查。
Deprecated
-
现在不推荐使用链接
classmethod
描述符(在bpo-19072中引入)。它不能再用于包装其他描述符,例如property
. 此功能的核心设计存在缺陷,并导致了许多下游问题。要“传递” aclassmethod
,请考虑使用__wrapped__
Python 3.10 中添加的属性。(由 Raymond Hettinger 在gh-89519中提供。) -
字符串和字节文字中的八进制转义值大于
0o377
现在产生的值DeprecationWarning
。在未来的 Python 版本中,它们将是 aSyntaxWarning
并且最终是SyntaxError
. (由 Serhiy Storchaka 在gh-81548中提供。) -
该
lib2to3
包和2to3
工具现已弃用,可能无法解析 Python 3.10 或更高版本。见PEP 617(CPython 的新 PEG 解析器)。(由 Victor Stinner 在bpo-40360中贡献。) -
未记录的模块
sre_compile
,sre_constants
现在sre_parse
已弃用。(由 Serhiy Storchaka 在bpo-47152中贡献。) -
webbrowser.MacOSX
已弃用并将在 Python 3.13 中删除。它未经测试和未记录,也没有被 webbrowser 本身使用。(由 Dong-hee Na 在bpo-42255中提供。) -
从 a
TestCase
和IsolatedAsyncioTestCase
test 方法返回值的行为(默认None
值除外)现在已弃用。 -
已弃用以下
unittest
函数,计划在 Python 3.13 中删除:-
unittest.findTestCases()
-
unittest.makeSuite()
-
unittest.getTestCaseNames()
改用
TestLoader
方法:(由 Erlend E. Aasland 在bpo-5846中贡献。)
-
-
自
turtle.RawTurtle.settiltangle()
Python 3.1 起已弃用,现在它会发出弃用警告,并将在 Python 3.13 中删除。改为使用turtle.RawTurtle.tiltangle()
(它之前被错误地标记为已弃用,现在更正了它的文档字符串)。(由 Hugo van Kemenade 在bpo-45837中贡献。) -
int()
to的委托__trunc__()
现在已被弃用。调用int(a)
何时type(a)
实现__trunc__()
但未 实现__int__()
或__index__()
现在会引发DeprecationWarning
. (由 Zackery Spytz 在bpo-44977中贡献。) -
configparser
自 Python 3.2 起,以下内容已被弃用。他们的弃用警告现在已经更新,注意他们将在 Python 3.12 中删除:-
configparser.SafeConfigParser
班级_ -
configparser.ParsingError.filename
财产_ -
configparser.RawConfigParser.readfp()
方法_
(由 Hugo van Kemenade 在bpo-45173中贡献。)
-
-
configparser.LegacyInterpolation
自 Python 3.2 起已在文档字符串中弃用。它现在发出 aDeprecationWarning
并将在 Python 3.13 中删除。使用configparser.BasicInterpolation
或configparser.ExtendedInterpolation
代替。(由 Hugo van Kemenade 在bpo-46607中贡献。) -
该
locale.getdefaultlocale()
函数已弃用,将在 Python 3.13 中删除。改用locale.setlocale()
,locale.getpreferredencoding(False)
和locale.getlocale()
函数。(由 Victor Stinner 在gh-90817中提供。) -
该
locale.resetlocale()
函数已弃用,将在 Python 3.13 中删除。改为使用。(由 Victor Stinner 在gh-90817中提供。)locale.setlocale(locale.LC_ALL, "")
-
和模块至少从 Python 3.6 开始就被弃用了
asynchat
。他们的文档和弃用警告现已更新,注意它们将在 Python 3.12 中删除(asyncore
smtpd
594)。(由 Hugo van Kemenade 在bpo- 47022 中贡献。) -
PEP 594导致以下模块被弃用,这些模块计划在 Python 3.13 中删除:
-
现在将在未来的 Python 版本中对正则表达式中的数字组引用和组名应用更严格的规则。现在只接受 ASCII 数字序列作为数字参考。字节模式和替换字符串中的组名只能包含 ASCII 字母和数字以及下划线。目前,针对此类语法会发出弃用警告。(由 Serhiy Storchaka 在gh-91760中提供。)
-
typing.Text
,它的存在只是为了提供 Python 2 和 Python 3 代码之间的兼容性支持,现在已被弃用。目前没有计划将其移除,但鼓励用户str
尽可能使用它。(由 Alex Waygood 在gh-92332中提供。) -
TypedDict
现在不推荐使用用于构造类型的关键字参数语法。支持将在 Python 3.13 中删除。(由叶景琛在gh-90224 供稿。) -
该
re.template()
函数和相应的re.TEMPLATE
和re.T
标志已被弃用,因为它们没有被记录在案并且缺乏明显的用途。它们将在 Python 3.13 中被移除。(由 Serhiy Storchaka 和 Miro Hrončok 在gh-92728中贡献。)
Python 3.12 中的待删除
以下 API 在早期的 Python 版本中已被弃用,并将在 Python 3.12 中删除。
Python API:
-
importlib.util.set_loader_wrapper()
-
importlib.util.set_package_wrapper()
-
importlib.abc.Loadermodule_repr()
-
importlib.machinery.BuiltinImporter.find_module()
-
importlib.machinery.BuiltinLoader.module_repr()
-
importlib.machinery.FileFinder.find_module()
-
importlib.machinery.FrozenImporter.find_module()
-
importlib.machinery.FrozenLoader.module_repr()
-
importlib.machinery.WindowsRegistryFinder.find_module()
-
cgi.log()
-
sqlite3.OptimizedUnicode()
-
sqlite3.enable_shared_cache()
C API:
-
PyUnicode_IS_COMPACT()
-
PyUnicode_IS_READY()
-
Py_UNICODE_WSTR_LENGTH()
-
_PyUnicode_AsUnicode()
-
PyUnicode_InternImmortal()
Removed
-
smtpd.MailmanProxy
现在已删除,因为没有外部模块就无法使用mailman
. (由 Dong-hee Na 在bpo-35800中提供。) -
该
binhex
模块在 Python 3.9 中已弃用,现在已删除。在 Python 3.9 中不推荐使用的以下binascii
函数现在也被删除:-
a2b_hqx()
,b2a_hqx()
; -
rlecode_hqx()
,rledecode_hqx()
.
该
binascii.crc_hqx()
功能仍然可用。(由 Victor Stinner 在bpo-45085中贡献。)
-
-
bdist_msi
在 Python 3.9 中不推荐使用的 distutils命令现在已被删除。改用bdist_wheel
(车轮包)。(由 Hugo van Kemenade 在bpo-45124中贡献。) -
由于重大的安全问题, Python 3.9 中禁用的 的_reuse_address_参数
asyncio.loop.create_datagram_endpoint()
现在已完全删除。这是因为SO_REUSEADDR
UDP 中套接字选项的行为。(由 Hugo van Kemenade 在bpo-45129中贡献。) -
自Python 3.9 起已不推荐使用和 的
__getitem__()
方法 。(由 Hugo van Kemenade 在bpo-45132中贡献。)xml.dom.pulldom.DOMEventStream
wsgiref.util.FileWrapper
fileinput.FileInput
-
gettext
模块中删除了以下不推荐使用的函数和方法:lgettext()
、ldgettext()
和 。lngettext()``ldngettext()
Function
bind_textdomain_codeset()
、 methodsoutput_charset()
和set_output_charset()
以及函数的_codeset_ 参数translation()
andinstall()
也被删除,因为它们仅用于l*gettext()
函数。(由 Dong-hee Na 和 Serhiy Storchaka 在bpo-44235中贡献。) -
使基于生成器的旧协程与 async/await 代码兼容的
@asyncio.coroutine
装饰器。该函数自 Python 3.8 起已被弃用,最初计划在 Python 3.10 中删除。改为使用。(由 Illia Volochii 在bpo-43216中贡献。)async def
-
asyncio.coroutines.CoroWrapper
用于在调试模式下包装遗留的基于生成器的协程对象。(由 Illia Volochii 在bpo-43216中贡献。) -
删除了已弃用
split()
的_tkinter.TkappType
. (由 Erlend E. Aasland 在bpo-38371中贡献。) -
从
inspect
模块中删除:-
该
getargspec
函数,自 Python 3.0 起已弃用;使用inspect.signature()
orinspect.getfullargspec()
代替。 -
该
formatargspec
函数,自 Python 3.5 起已弃用;直接使用inspect.signature()
函数和Signature
对象。 -
自 Python 3.5 起已弃用的未记录
Signature.from_builtin
和Signature.from_function
函数;改用该Signature.from_callable()
方法。
(由 Hugo van Kemenade 在bpo-45320中贡献。)
-
-
从 unittest 发现中删除命名空间包支持。它是在 Python 3.4 中引入的,但自 Python 3.7 以来已被破坏。(由 Inada Naoki 在bpo-23882中贡献。)
-
从 中删除
__class_getitem__
方法pathlib.PurePath
,因为在以前的版本中没有使用和错误添加。(由 Nikita Sobolev 在bpo-46483中贡献。) -
删除未记录的私有方法,以前在 Python 3.7 中
float.__set_format__()
称为。float.__setformat__()
它的文档字符串说:“你可能不想使用这个函数。它的存在主要是为了在 Python 的测试套件中使用。” (由 Victor Stinner 在bpo-46852中贡献。) -
--experimental-isolated-subinterpreters
配置标志(和相应的EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
)已被删除。
移植到 Python 3.11
本节列出了之前描述的更改和其他可能需要更改代码的错误修正。
Python API 的变化
-
禁止传递非
concurrent.futures.ThreadPoolExecutor
执行者loop.set_default_executor()
遵循 Python 3.8 中的弃用。(由 Illia Volochii 在bpo- 43234 中贡献。) -
open()
,io.open()
,codecs.open()
并且 在文件模式下fileinput.FileInput
不再接受'U'
(“通用换行符”)。此标志自 Python 3.3 起已弃用。在 Python 3 中,当文件以文本模式打开时,默认使用“通用换行符”。的 换行参数open()
控制通用换行的工作方式。(由 Victor Stinner 在bpo-37330中贡献。) -
该
pdb
模块现在读取带有编码的.pdbrc
配置文件。'utf-8'
(由 Srinivas Reddy Thatiparthy 在bpo-41137中贡献。) -
calendar
:如果未指定语言环境,则calendar.LocaleTextCalendar
andcalendar.LocaleHTMLCalendar
类现在使用locale.getlocale()
,而不是 using 。locale.getdefaultlocale()
(由 Victor Stinner 在bpo-46659中贡献。) -
全局内联标志(例如
(?i)
)现在只能在正则表达式的开头使用。自 Python 3.6 以来,不推荐在表达式开头使用它们。(由 Serhiy Storchaka 在bpo-47066中贡献。) -
re
模块:修复了一些长期存在的错误,在极少数情况下,捕获组可能会得到错误的结果。所以结果可能与以前不同。(由马林在bpo-35859中贡献。) -
的_人口_参数
random.sample()
必须是一个序列。不再支持将集合自动转换为列表。如果样本大小大于总体大小,ValueError
则提高 a。(由 Raymond Hettinger 在bpo-40465中贡献。) -
ast.AST
compile()
现在在提供给和其他相关功能时验证节点位置 。如果检测到无效位置,ValueError
将引发 a。(由 Pablo Galindo 在gh-93351中提供) -
tp_dictoffset
应被视为只写。可以设置为向VM描述C扩展类,但阅读时应视为无意义。改为获取指向对象字典调用的指针PyObject_GenericGetDict()
。
构建更改
-
构建 Python 现在需要 C11 编译器。不需要可选的 C11 功能。(由 Victor Stinner 在bpo-46656中贡献。)
-
构建 Python 现在需要支持 IEEE 754 浮点数。(由 Victor Stinner 在bpo-46917中贡献。)
-
现在可以使用 ThinLTO 选项通过
--with-lto=thin
. (由 Dong-hee Na 和 Brett Holman 在bpo-44340中贡献。) -
libpython 不再与 libcrypt 链接。(由 Mike Gilbert 在bpo-45433中贡献。)
-
构建 Python 现在需要一个
<math.h>
提供以下函数的 C99 头文件:copysign()
,hypot()
,isfinite()
,isinf()
,isnan()
,round()
. (由 Victor Stinner 在bpo-45440中贡献。) -
构建 Python 现在需要一个
<math.h>
提供NAN
常量或__builtin_nan()
内置函数的 C99 头文件。(由 Victor Stinner 在bpo-46640中贡献。) -
构建 Python 现在需要支持浮点非数字 (NaN):删除
Py_NO_NAN
宏。(由 Victor Stinner 在bpo-46656中贡献。) -
现在可以禁用对象结构的空闲列表。一个新的配置 选项
--without-freelists
可用于禁用除空元组单例之外的所有空闲列表。(由 Christian Heimes 在bpo-45522中贡献。) -
Modules/Setup
并Modules/makesetup
进行了改进和捆绑。扩展模块现在可以通过makesetup
. 除了一些测试模块之外的所有模块都可以静态链接到主二进制文件或库中。(由 Brett Cannon 和 Christian Heimes 在bpo-45548、 bpo-45570、bpo-45571和bpo-43974 中贡献。) -
configure现在可以检测大多数 stdlib 扩展模块的构建依赖项、编译器标志和链接器标志。libffi、libnsl、libsqlite3、zlib、bzip2、liblzma、libcrypt、Tcl/Tk 和 uuid 标志由
pkg-config
(如果可用)检测。tkinter
现在需要pkg-config
命令来检测 Tcl/Tk 头文件和库的开发设置。(由 Christian Heimes 和 Erlend Egeberg Aasland 在 bpo-45847、bpo-45747和bpo-45763 中贡献。)备注
使用环境变量
TCLTK_CFLAGS
和TCLTK_LIBS
手动指定 Tcl/Tk 头文件和库的位置。配置选项和已被删除--with-tcltk-includes
。--with-tcltk-libs
在 RHEL 7 和 CentOS 7 上,开发包不提供
tcl.pc
和tk.pc
,使用TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5"
. 该目录Misc/rhel7
包含.pc
如何使用 RHEL 7 和 CentOS 7 的 Tcl/Tk 和 OpenSSL 构建 Python 的文件和说明。 -
CPython 现在有PEP 11第 3 层支持交叉编译到 WebAssembly 平台
wasm32-unknown-emscripten
(浏览器中的 Python)。这项工作受到了Pyodide等先前工作的启发。Emscripten 提供了有限的 POSIX API 子集。与网络、进程、线程、信号、mmap 和用户/组相关的 Python 标准库功能和模块不可用或不起作用。(由 Christian Heimes 和 Ethan Smith 在gh-84461 中贡献,在 gh-95085中推广) -
CPython 现在有PEP 11第 3 层支持交叉编译到 WebAssembly 平台
wasm32-unknown-wasi
(WebAssembly 系统接口)。与 Emscripten 一样,WASI 上只有 Python 标准库的一个子集。(由 Christian Heimes 在gh-90473中贡献,在gh-95085中推广) -
CPython 现在将默认使用 30 位数字来
int
实现 Python。以前,默认是在带有 的平台上使用 30 位数字,否则使用 15 位数字。仍然可以通过配置脚本的选项或(对于 Windows)中的 变量显式请求使用 15 位数字 ,但将来可能会删除此选项。(由 Mark Dickinson 在 bpo-45569中贡献。)SIZEOF_VOID_P >= 8``--enable-big-digits``PYLONG_BITS_IN_DIGIT``PC/pyconfig.h
-
该
tkinter
软件包现在需要 Tcl/Tk 版本 8.5.12 或更高版本。(由 Serhiy Storchaka 在bpo-46996中贡献。)
C API 更改
新功能
-
添加一个新
PyType_GetName()
函数来获取类型的短名称。(由 Hai Shi 在bpo-42035中贡献。) -
添加一个新
PyType_GetQualName()
函数来获取类型的限定名称。(由 Hai Shi 在bpo-42035中贡献。) -
向有限的 C API添加新函数
PyThreadState_EnterTracing()
和PyThreadState_LeaveTracing()
函数以暂停和恢复跟踪和分析。(由 Victor Stinner 在bpo-43760中贡献。) -
添加了
Py_Version
与 具有相同值的常数PY_VERSION_HEX
。(由 Gabriele N. Tornetta 在bpo-43931中贡献。) -
Py_buffer
API 现在是受限 API 和稳定 ABI 的一部分:-
PyBuffer_CopyData()
(由 Christian Heimes 在bpo-45459中贡献。)
-
添加了
PyType_GetModuleByDef
函数,用于获取定义方法的模块,以防无法直接获得此信息(通过PyCMethod
)。(由 Petr Viktorin 在bpo-46613中贡献。) -
添加新函数以打包和解包 C 双精度(序列化和反序列化) :
PyFloat_Pack2()
、PyFloat_Pack4()
、PyFloat_Pack8()
、PyFloat_Unpack2()
和. (由 Victor Stinner 在bpo-46906中贡献。)PyFloat_Unpack4()
PyFloat_Unpack8()
-
添加新函数以获取框架对象属性:
PyFrame_GetBuiltins()
,PyFrame_GetGenerator()
,PyFrame_GetGlobals()
,PyFrame_GetLasti()
. -
添加了两个新函数来获取和设置活动异常实例:
PyErr_GetHandledException()
和PyErr_SetHandledException()
. 这些是异常的传统 3 元组表示的替代方案,并且可以PyErr_SetExcInfo()
与 它们一起使用。PyErr_GetExcInfo()
(由 Irit Katriel 在bpo-46343中贡献。) -
添加了
PyConfig.safe_path
成员。(由 Victor Stinner 在gh-57684中提供。)
移植到 Python 3.11
-
PyErr_SetExcInfo()
不再使用type
and参数,解释器现在从异常实例(参数)traceback
派生这些值。value
该函数仍然窃取所有三个参数的引用。(由 Irit Katriel 在bpo-45711中贡献。) -
PyErr_GetExcInfo()
现在 从异常实例(字段)派生结果的type
和字段。(由 Irit Katriel 在bpo-45711中贡献。)traceback``value
-
_frozen
有一个新is_package
字段来指示冻结的模块是否是一个包。以前,该字段中的负值size
是指标。现在只有非负值用于size
. (由 Kumar Aditya 在bpo-46608中贡献。) -
_PyFrameEvalFunction()
现在将_PyInterpreterFrame*
其作为第二个参数,而不是PyFrameObject*
. 看PEP 523有关如何使用此函数指针类型的更多详细信息。 -
PyCode_New()
现在PyCode_NewWithPosOnlyArgs()
采取一个额外的exception_table
论点。如果可能的话,应该避免使用这些函数。获取自定义代码对象:使用编译器创建代码对象,然后使用该replace
方法获取修改后的版本。 -
PyCodeObject
不再具有co_code
、co_varnames
和co_cellvars
字段co_freevars
。相反,使用 、 和PyCode_GetCode()
分别PyCode_GetVarnames()
通过 C API 访问它们。(由 Brandt Bucher 在bpo-46841和 Ken Jin 在gh-92154 和gh-94936 中贡献。)PyCode_GetCellvars()
PyCode_GetFreevars()
-
旧的垃圾桶宏 (
Py_TRASHCAN_SAFE_BEGIN
/Py_TRASHCAN_SAFE_END
) 现在已弃用。它们应该被新的宏Py_TRASHCAN_BEGIN
和Py_TRASHCAN_END
.具有旧宏的 tp_dealloc 函数,例如:
static void mytype_dealloc(mytype *p) { PyObject_GC_UnTrack(p); Py_TRASHCAN_SAFE_BEGIN(p); ... Py_TRASHCAN_SAFE_END }
应迁移到新的宏,如下所示:
static void mytype_dealloc(mytype *p) { PyObject_GC_UnTrack(p); Py_TRASHCAN_BEGIN(p, mytype_dealloc) ... Py_TRASHCAN_END }
请注意,
Py_TRASHCAN_BEGIN
第二个参数应该是它所在的释放函数。为了在同一个代码库中支持较旧的 Python 版本,您可以定义以下宏并在整个代码中使用它们(信用:这些是从
mypy
代码库中复制的):#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8 # define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc) # define CPy_TRASHCAN_END(op) Py_TRASHCAN_END #else # define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_SAFE_BEGIN(op) # define CPy_TRASHCAN_END(op) Py_TRASHCAN_SAFE_END(op) #endif
-
现在,如果使用设置的标志定义类型但没有遍历函数 ( ) ,则该
PyType_Ready()
函数会引发错误。(由 Victor Stinner 在bpo-44263中贡献。)Py_TPFLAGS_HAVE_GC
PyTypeObject.tp_traverse
-
带有标志的堆类型
Py_TPFLAGS_IMMUTABLETYPE
现在可以继承PEP 590向量调用协议。以前,这仅适用于 静态类型。(由 Erlend E. Aasland 在bpo-43908中贡献) -
由于
Py_TYPE()
更改为内联静态函数, 因此必须替换为 :查看函数(自 Python 3.9 起可用)。为了向后兼容,可以使用此宏:Py_TYPE(obj) = new_type``Py_SET_TYPE(obj, new_type)
Py_SET_TYPE()
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { ob->ob_type = type; } #define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type) #endif
(由 Victor Stinner 在bpo-39573中贡献。)
-
由于
Py_SIZE()
更改为内联静态函数, 因此必须替换为 :查看函数(自 Python 3.9 起可用)。为了向后兼容,可以使用此宏:Py_SIZE(obj) = new_size``Py_SET_SIZE(obj, new_size)
Py_SET_SIZE()
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { ob->ob_size = size; } #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) #endif
(由 Victor Stinner 在bpo-39573中贡献。)
-
<Python.h>
不再包含头文件, 和<stdlib.h>
当<stdio.h>
宏设置 为(Python 3.11) 或更高版本时。C 扩展应该在. (由 Victor Stinner 在bpo-45434中贡献。)<errno.h>``<string.h>``Py_LIMITED_API``0x030b0000``#include <Python.h>
-
不受限制的 API 文件、
cellobject.h
、classobject.h
、code.h
、context.h
和funcobject.h
已移至目录。此外,头文件已被删除。这些文件不能直接包含,因为它们已经包含在:Include Files中。如果它们已被直接包含,请考虑改为包含。(由 Victor Stinner 在bpo-35134中贡献。)genobject.h``longintrepr.h``Include/cpython``eval.h``Python.h
Python.h
-
该
PyUnicode_CHECK_INTERNED()
宏已从有限的 C API 中排除。它在那里永远无法使用,因为它使用了有限的 C API 中不可用的内部结构。(由 Victor Stinner 在bpo-46007中贡献。) -
现在可以直接使用以下框架功能和类型 ,不再需要添加 :
#include <Python.h>``#include <frameobject.h>
-
PyFrame_Check()
-
PyFrame_Type
(由 Victor Stinner 在gh-93937中提供。)
-
-
PyFrameObject
结构成员已从公共 C API 中删除。虽然文档指出这些
PyFrameObject
字段随时可能发生变化,但它们已经稳定了很长时间,并被用于几个流行的扩展中。在 Python 3.11 中,frame 结构被重新组织以允许性能优化。一些字段被完全删除,因为它们是旧实现的细节。
-
f_back
: 使用PyFrame_GetBack()
。 -
f_blockstack
: 删除。 -
f_builtins
: 使用PyFrame_GetBuiltins()
。 -
f_code
: 使用PyFrame_GetCode()
。 -
f_gen
: 使用PyFrame_GetGenerator()
。 -
f_globals
: 使用PyFrame_GetGlobals()
。 -
f_iblock
: 删除。 -
f_lasti
: 使用PyFrame_GetLasti()
。使用f_lasti
with 的代码PyCode_Addr2Line()
应该PyFrame_GetLineNumber()
改用;它可能会更快。 -
f_lineno
: 利用PyFrame_GetLineNumber()
-
f_locals
: 使用PyFrame_GetLocals()
。 -
f_stackdepth
: 删除。 -
f_state
:没有公共 API(重命名为f_frame.f_state
)。 -
f_trace
: 没有公共 API。 -
f_trace_lines
: 使用。PyObject_GetAttrString((PyObject*)frame, "f_trace_lines")
-
f_trace_opcodes
: 使用。PyObject_GetAttrString((PyObject*)frame, "f_trace_opcodes")
-
f_localsplus
:没有公共 API(重命名为f_frame.localsplus
)。 -
f_valuestack
: 删除。
Python 框架对象现在是延迟创建的。一个副作用是
f_back
不能直接访问该成员,因为它的值现在也是延迟计算的。PyFrame_GetBack()
必须改为调用该函数。f_locals
直接访问的调试器_必须_调用PyFrame_GetLocals()
。他们不再需要调用PyFrame_FastToLocalsWithError()
orPyFrame_LocalsToFast()
,事实上他们不应该调用那些函数。框架的必要更新现在由虚拟机管理。PyFrame_GetCode()
在 Python 3.8 和更早版本上定义的代码:#if PY_VERSION_HEX < 0x030900B1 static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) { Py_INCREF(frame->f_code); return frame->f_code; } #endif
PyFrame_GetBack()
在 Python 3.8 和更早版本上定义的代码:#if PY_VERSION_HEX < 0x030900B1 static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) { Py_XINCREF(frame->f_back); return frame->f_back; } #endif
或者使用pythoncapi_compat 项目在较旧的 Python 版本上获取这两个函数。
-
-
PyThreadState
结构成员的变化:-
frame
:删除,使用(由bpo-40429PyThreadState_GetFrame()
添加到 Python 3.9 的函数)。警告:函数返回强引用,需要调用 。Py_XDECREF()
-
tracing
:更改、使用PyThreadState_EnterTracing()
和(由bpo-43760PyThreadState_LeaveTracing()
添加到 Python 3.11 的函数)。 -
recursion_depth
: 删除,改用。(tstate->recursion_limit - tstate->recursion_remaining)
-
stackcheck_counter
: 删除。
PyThreadState_GetFrame()
在 Python 3.8 和更早版本上定义的代码:#if PY_VERSION_HEX < 0x030900B1 static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { Py_XINCREF(tstate->frame); return tstate->frame; } #endif
代码定义
PyThreadState_EnterTracing()
和PyThreadState_LeaveTracing()
Python 3.10 及更早版本:#if PY_VERSION_HEX < 0x030B00A2 static inline void PyThreadState_EnterTracing(PyThreadState *tstate) { tstate->tracing++; #if PY_VERSION_HEX >= 0x030A00A1 tstate->cframe->use_tracing = 0; #else tstate->use_tracing = 0; #endif } static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) { int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); tstate->tracing--; #if PY_VERSION_HEX >= 0x030A00A1 tstate->cframe->use_tracing = use_tracing; #else tstate->use_tracing = use_tracing; #endif } #endif
或者使用pythoncapi_compat 项目在旧的 Python 函数上获取这些函数。
-
-
鼓励分销商使用优化的 Blake2 库libb2构建 Python 。
-
该
PyConfig.module_search_paths_set
字段现在必须设置为 1 才能用于PyConfig.module_search_paths
初始化sys.path
。否则,初始化将重新计算路径并替换添加到module_search_paths
. -
PyConfig_Read()
不再计算初始搜索路径,并且不会将任何值填充到PyConfig.module_search_paths
. 要计算默认路径然后修改它们,完成初始化并使用作为 Python 列表对象PySys_GetObject()
检索并直接修改它。sys.path
Deprecated
-
弃用以下函数来配置 Python 初始化:
-
PySys_HasWarnOptions()
-
_Py_SetProgramFullPath()
请改用Python 初始化配置的新
PyConfig
API (PEP 587)。(由 Victor Stinner 在gh-88279中提供。) -
弃用.
ob_shash
_PyBytesObject
改为使用PyObject_Hash()
。(由 Inada Naoki 在bpo-46864中贡献。)
Removed
-
PyFrame_BlockSetup()
并PyFrame_BlockPop()
已被删除。(由 Mark Shannon 在bpo-40222中贡献。) -
errno
使用变量删除以下数学宏:-
Py_ADJUST_ERANGE1()
-
Py_ADJUST_ERANGE2()
-
Py_OVERFLOWED()
-
Py_SET_ERANGE_IF_OVERFLOW()
-
Py_SET_ERRNO_ON_MATH_ERROR()
(由 Victor Stinner 在bpo-45412中贡献。)
-
-
删除
Py_UNICODE_COPY()
和Py_UNICODE_FILL()
宏,自 Python 3.3 起已弃用。使用PyUnicode_CopyCharacters()
或memcpy()
(wchar_t*
字符串)和PyUnicode_Fill()
函数代替。(由 Victor Stinner 在bpo-41123中贡献。) -
删除
pystrhex.h
头文件。它只包含私有函数。C 扩展应该只包含主<Python.h>
头文件。(由 Victor Stinner 在bpo-45434中贡献。) -
删除
Py_FORCE_DOUBLE()
宏。它被Py_IS_INFINITY()
宏使用。(由 Victor Stinner 在bpo-45440中贡献。) -
Py_LIMITED_API
以下项目在定义时不再可用:-
Py_MARSHAL_VERSION
宏_
这些不是受限 API的一部分。
(由 Victor Stinner 在bpo-45474中贡献。)
-
PyWeakref_GET_OBJECT()
从受限的 C API 中排除。由于PyWeakReference
结构在有限的 C API 中是不透明的,因此它从未起作用。(由 Victor Stinner 在bpo-35134中贡献。) -
删除
PyHeapType_GET_MEMBERS()
宏。它被错误地暴露在公共 C API 中,只能由 Python 内部使用。请改用该PyTypeObject.tp_members
成员。(由 Victor Stinner 在bpo-40170中贡献。) -
删除
HAVE_PY_SET_53BIT_PRECISION
宏(移至内部 C API)。(由 Victor Stinner 在bpo-45412中贡献。) -
删除
Py_UNICODE
编码器 API,因为它们自 Python 3.3 以来已被弃用,很少使用并且相对于推荐的替代方案效率低下。删除的功能是:
-
PyUnicode_Encode()
-
PyUnicode_EncodeASCII()
-
PyUnicode_EncodeLatin1()
-
PyUnicode_EncodeUTF7()
-
PyUnicode_EncodeUTF8()
-
PyUnicode_EncodeUTF16()
-
PyUnicode_EncodeUTF32()
-
PyUnicode_EncodeUnicodeEscape()
-
PyUnicode_EncodeRawUnicodeEscape()
-
PyUnicode_EncodeCharmap()
-
PyUnicode_TranslateCharmap()
-
PyUnicode_EncodeDecimal()
-
PyUnicode_TransformDecimalToASCII()
-
评论区