更快的解释器,更易懂的错误,更强大的类型提示,以及其他一系列的加速和调整,现在都可以试用了。

Python 每年都会发布新版本,上半年是功能锁定的测试版,年底是最终版本。

Python 3.11 的特性集刚刚定稿,测试版本已经发布,开发人员在非生产代码上可以尝试使用这个最新版本,验证它能否在你的程序中工作,并了解你的程序是否能从本次性能增加中受益。

下面是 Python 3.11 中最重要新特性的概述,以及它们对 Python 开发者的意义。

提速

在 Python 3.11 中,有许多单独的性能改进,最大的一个新功能是自适应解释器,由于对象的类型很少更改,解释器现在尝试分析正在运行的代码,并用类型特定的字节码替换常规字节码。例如,二进制操作(加法、减法等)可以被替换为整数、浮点和字符串的特殊版本替换。

Python 函数调用在 Python 3.11 中也需要更少的开销,用于函数调用的堆栈使用的内存更少,而且设计得更有效。此外,虽然递归调用没有尾部优化(在 Python 中是不可能的) ,但它们比以前的版本更有效率,Python 解释器本身的启动速度也更快, 运行时所需的核心模块的存储和加载效率也更高。

根据官方的 Python 基准测试套件,Python 3.11 运行速度比 3.10 快 1.25 倍。注意,这个速度提升是一个综合的衡量标准,有些事情要快得多,但许多其他事情只是稍快一点或者大致相同。这些改进是无限制的,你不需要对原 Python 程序进行任何修改,就可以享受 3.11 的速度提升。

增强错误信息

Python 3.11 中另一个有用的特性是更详细的错误信息,Python 3.10 已经有了更好的错误报告,这要归功于解释器中使用新的分析器。现在,Python 3.11 在此基础上进行了扩展,提供了关于给定表达式的哪个具体部分导致错误的详细反馈。

3.11 中另一个非常有用的特性是更详细的错误消息,由于解释器中使用了新的解析器,Python 3.10 已经有了更好的错误报告。现在,Python 3.11 对此进行了扩展,提供了给定表达式的哪个具体部分导致错误的详细反馈。

考虑以下代码,它抛出了一个错误:

1.x = [1,2,3]  
2.z = x[1][0]1.2.

在 Python 3.10 中,我们会收到下面的错误消息,这并不是很有帮助:

1. File "C:\Python311\code.py", line 2, in <module>  
2.    z = x[1][0]  
TypeError: 'int' object is not subscriptable1.2.3.

Python 3.11 中的错误跟踪直接指向生成错误的确切部分,而不是让我们猜测哪个 int 是不可编写的脚本。

1.File "C:\Python311\code.py", line 2, in <module>  
2.   z = x[1][0]  
3.       ~~~~^^^  
4.ypeError: 'int' object is not subscriptable1.2.3.4.

现在,问题出现在哪里已经没有歧义了。

改进异常

在 Python 3.11 中,Python 的错误处理机制 Exceptions 获得了许多新特性:

  • 通过新的 except * 语法和新的 ExceptionGroup 异常类型,可以一次引发和处理多个异常,例如在处理异步或并发方法时,或者在重试操作时处理多个失败时,它可以更优雅的处理。

  • Zero-cost 异常:异常现在对程序没有任何成本,除非它们真的被引发,这意味着 try/except 代码块会更快,并使用更少的内存。

  • 捕获异常所需的时间减少了 10% 左右。

  • 异常可以与本身的文本分开,并通过上下文注释来丰富。

改进类型

Python 的类型提示功能使更大的代码库容易管理和分析,并且自 Python 3.5 以来的每次修订都有显著的增长,Python 3.11 带来了几个新的类型提示功能。

自我类型

以前,类方法 return self 需要复杂而冗长的注解才能发挥作用, typing.Self 可以简单的将类方法的返回值注释为 Self,你可以从分析工具中得到有用和可预测的结果。

任意的字符串字面类型

以前,类型注解无法指示给定的变量必须是字符串字面量(即源代码中定义的字符串)。新的 typing.LiteralString 注解修复了这个问题,使用新的注解,字面量可以测试变量是在源码中定义的字符串,还是由源代码定义的字符串组成的新字符串。

数据类转换

从 Python 3.7 开始,数据类使定义类更加容易,这些类遵循通用模式,根据它们的初始化参数创建属性。但没有标准的机制来允许表现得像数据类(但不是数据类)的内容,使用类型注解来声明它们的行为,数据类转换添加装饰器 typing.Dataclass _ transform 指示给定的函数、类或元类像数据类一样工作。

可变参数泛型

类型提示的最初提议包括 TypeVar ,它是一种使用单一参数类型来指定泛型函数的方法,例如,类型 T 可以是 int 或 float ,Python 3.11 添加了 TypeVarTuple 或者 “variadic generics” ,你可以使用它来指定占位符,不仅是一种类型,而且是一系列类型,表现形式为元组,在 NumPy 之类的库中特别有用,在这些库中,你可以提前执行错误检查,比如判断输入数组是否正确。

标准库中的 TOML 只读支持

Python 使用 TOML(即 Tom’s Obvious Minimal Language)作为配置格式 (如 pyproject.toml),但没有将读取 TOML 格式文件的能力作为一个标准库模块公开。Python 3.11 增加了 tomllib 来解决这个问题,注意 tomllib 不能创建或写入 TOML 文件,因此你需要一个第三方模块,如 Tomli-W 或 TOML Kit 。

正则表达式的原子组和提速

用于处理正则表达式的 re 模块,缺少其他正则表达式实现中的一些特性。一种是原子组,在其他语言中得到广泛支持,Python 3.11 现在使用通用的原子分组语法(例如, (? > ...) )。

re 模块的模式匹配引擎也进行了一些重写,运行速度提高了 10% 。

从标准库中删除“dead batteries”

PEP 594 启动了一项工作,从 Python 标准库中删除了许多所谓的“dead batteries”,即过时或未维护的模块,在 Python 3.11 中,这些库被标记为已弃用但尚未删除; 它们将在 Python 3.13 中完全删除。

Python 3.11 其他的新增内容、修正和变化

在 Python 3.11 中还有更多的小改进:

  • Python 对象需要更少的内存,因为它们的名称空间现在是延迟创建的,并且它们的名称空间字典会尽可能的共享键。

  • 所有键都是 Unicode 的字典,而且不再需要存储散列,从而减少了字典的大小,并提高了缓存效率。

  • CPython 运行时(Python 解释器),现在已经有了编译到 WebAssembly 的实验性支持,这可能有助于像 PyScript 这种项目的未来发展,它允许一个 WASM 编译的 Python 运行时在浏览器中运行。

译者介绍

王德朕,51CTO社区编辑,10年互联网产研经验,6年IT教培行业经验。原K12教育上市公司产品经理,技术博客专家,蓝桥签约作者,《滚雪球学Python》专栏作者,《爬虫100例》专栏特约作者,78技术人社区发起者。

原文标题:The best new features and fixes in Python 3.11,作者:Serdar Yegulalp

链接:https://www.infoworld.com/article/3660550/the-best-new-features-and-fixes-in-python-311.html