Python 3.12 引入了一系列显著的特性和改进,进一步提升了开发者的体验和语言的性能。该版本在错误消息方面做了重要改进,提供了更详细且富有指导性的提示,帮助开发者更快定位问题。格式化字符串(f-strings)的功能也得到了增强,允许更强大的字符串格式化。
在性能优化方面,Python 3.12 继续推进 faster-cpython 项目,通过加速和专门化字节码执行,显著提升了代码的运行速度。该版本还改进了列表推导和其他推导操作的执行效率,使得数据处理更加高效。
此外,Python 3.12 支持 Linux perf Profiler,为性能分析提供了更多工具。每个子解释器现在配备独立的 GIL(全局解释器锁),提高了并发性能。新增了不可变对象和用于显式继承的覆盖装饰器,并引入了 itertools.batched() 方法以便将可迭代对象中的项目分组,以及改进了 Path.walk() 方法以列出文件和子目录。这些改进进一步增强了 Python 作为开发语言的功能性和灵活性。
改进的错误消息
在 Python 3.10 中,许多错误消息,尤其是语法错误消息,变得更加详细和准确。同样,Python 3.11 在追踪回溯信息中增加了更多内容,使得定位出错代码变得更加方便。
最新版本的 Python 3.12 继续改善开发者体验,提供了更好的错误消息。特别是一些常见的错误消息现在附带了有用的建议。
图片
当您在没有先导入 math 的情况下使用它时,您会得到一个传统的 NameError。此外,解析器会帮助提醒您在访问 math 之前需要导入它。
关于提示导入模块的提醒仅适用于标准库模块。对于这些错误消息,Python 3.12 不会跟踪安装的第三方包。
目前由于ipython有字节错误处理机制,提示导入包在ipython 里面没有实现。
图片
可以使用 from-import 语句从模块中导入特定名称。如果您不小心将关键字的顺序颠倒了,现在会得到一个友好的提示,指导您使用正确的语法:
图片
看看如果您从 math 模块导入 py 而不是 pi 会发生什么:
图片
更强大的 F-string
格式化字符串,简称 f-string,是在 PEP 498 和 Python 3.6 中引入的。通过 f-string,Python 增加了字符串格式化功能。您可以通过前导的 f 来识别 f-string,如以下示例:
图片
关于F-String 在python 3.12 新特征,可以参考:《一文带您了解F-string:解锁Python3.12下F-string的新特性》
更快的 Python:更多专门化和内联列表推导
当 Python 3.11 在 2022 年发布时,关于解释器优化的讨论非常热烈,这些优化使得 Python 变得更快。这项工作是名为 faster-cpython 的持续努力的一部分,并在 Python 3.12 中继续进行。
在 Python 脚本开始运行之前,代码会被转换成字节码。字节码是 Python 解释器执行的代码。Python 3.11 使用了一个专门的自适应解释器,它可以在执行过程中改变和调整字节码,以优化经常发生的操作。这包括两个步骤:
- 加速:识别某些字节码被多次执行,使其成为专门化的候选对象。
- 专门化:解释器将一般的字节码替换为专门化的字节码。例如,将两个浮点数相加的操作可以替换为一个专门化的加法操作。
在 Python 3.12 中,加速的过程比 Python 3.11 更快,解释器现在可以专门化更多的新字节码。要查看加速和专门化的实际效果,请定义以下函数:
图片
每一行显示有关一个字节码指令的信息。五列分别是行号、字节地址、操作码名称、操作参数,以及参数的解释(括号内)。
不需要理解这个字节码列表的细节。一行 Python 代码通常会编译成多个字节码指令,在这个例子中,return 0.3048 * feet 被翻译成四条字节码指令。
实际上,现在没有单独的加速步骤。原则上,所有字节码指令都立即准备好进行专门化。在 Python 3.11 中,专门化在字节码执行了相同类型八次后才开始。而python 3.12,这一过程在执行两次后就会发生:
图片
解释器调整了原始BINARY_OP指令,将其替换为BINARY_OP_MULTIPLY_FLOAT,当两个操作数都是float时,速度会更快。
解释器优化调整某些字节码,同时也不会损害 Python 的动态特性。仍然可以使用feet_to_meters()调整参数。使用相同数据类型的唯一好处是您的程序可能会运行得更快。
Python 支持列表推导、字典推导和集合推导,您可以使用它们来转换可迭代对象。例如:
图片
比如下面的列表推导式在以前python版本中,会编译为嵌套的字节代码,如下:
图片
而在pythyon 3.12 版本中,推导式被编译为内部字节代码,也在就是内联推导,大大加快的执行速度。如下图:
图片
此外Python 3.12 在多个方面进行了改进,包括对 Linux perf Profiler 的支持、每个子解释器一个 GIL 的机制,以及引入了不可变对象。此外,新增了用于显式继承的覆盖装饰器。该版本还引入了 itertools.batched() 方法,以便将可迭代对象中的项目分组,并改进了 Path.walk() 方法。