【Python】Python 3.11 新特性

前言:

本文介绍了 Python 3.11 与 3.10 相比的新功能。
(部分新功能)


一、新功能

1.1 (PEP 654)Exception Groupsexcept *

Python 3.11 之前,解释器同一时间只能捕获一个异常。

对于需要同时捕获的无关异常、链式异常无能为力:
(一种情况)当 Python 标准库中的上下文管理器在 __exit__() 中引发异常时,会覆盖用户引发的异常。虽然用户异常以 __context__的形式被保留,但是用户的 try...except...无法捕获到原始异常。

# Exception
def foo():
    try:
        raise print(1 / 0)
    except Exception as e:
        print(e)

-----------------------
division by zero
# ExceptionGroup
def foo():
    try:
        raise print(1 / 0)
    except ExceptionGroup as e:
        print(e)

-----------------------
Traceback (most recent call last):
  File "foo.py", line 26, in <module>
    foo()
  File "foo.py", line 20, in foo
    print(1 / 0)
          ~~^~~
ZeroDivisionError: division by zero

1.2 (PEP 655)TypeDict标记必须或非必须

from typing_extensions import Required, NotRequired, TypedDict

class Movie(TypedDict):
    title: str
    year: NotRequired[int]

# 等同上面定义内容
class Movie0(TypedDict, total=False):
    title: Required[str]
    year: int

描述

二、其他语言变化

2.1 在for语句中使用星号解包表达式

现在 python3.9 和 python3.10 中也以支持。

a = [1, 2, 3]
b = [4, 5, 6]
for x in *a, *b:
    print(x)

三、新模块

3.1 tomllib

import tomllib

with open("../pyproject.toml", "rb") as f:
    data: dict = tomllib.load(f)

toml_str = """
python-version = "3.11.0"
python-implementation = "CPython"
"""

data0 = tomllib.loads(toml_str)

3.2 wsgiref.types

用于静态类型检查的WSGI类型。

四、math

4.1 math.exp2()

返回 2 的 x 次方

4.2 math.cbrt()

返回 x 的立方根

4.3 math.pow()

为了与 IEEE 754 规范保持一致,更改了两个极端情况。

math.pow(0.0, -math.inf) -> inf
math.pow(-0.0, -math.inf) -> inf

# 之前以上函数返回 -> ValueError

4.4 math.nan

math.nan现在一直可用。

五、更快的 CPython

5.1 更快的启动

Python 将字节码缓存在 __pycache__ 目录中以加速模块加载。

之前,在 3.10 中,

Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate

在 Python 3.11 中,Python 启动必不可少的核心模块被冻结。

这意味着,它们的代码对象(字节码)是由解释器静态分配的。

这将模块执行过程中的步骤减少为:

Statically allocated code object -> Evaluate

Python 3.11 中的解释器启动速度现在提高到了 10 - 15%。这对使用 Python 的短时间运行程序有很大的影响。

5.2 更快的运行时间

每当 Python 调用 Python 函数时,就会创建 Python 框架。该帧保存执行信息,以下是新的框架优化:

  • 简化了框架创建过程
  • 通过大量重复使用 C 堆栈上的帧空间来避免内存分配
  • 简化内部框架结构,仅包含基本信息。帧以前包含额外的调试和内存管理信息。

5.3 内联 Python 函数调用

在 Python 函数调用期间,Python 将调用一个评估 C 函数来解释该函数的代码。这有效地将纯 Python 递归限制在对 C 堆栈安全的范围内。

在 3.11 中,当 CPython 检测到 Python 代码调用另一个 Python 函数时,它会建立一个新框架,并“跳转”到新框架内的新代码。这避免了完全调用 C 解释函数。

大多数 Python 函数调用现在不占用 C 堆栈空间。这加快了大多数此类调用的速度。

5.4 PEP 659:专门的自适应解释器

PEP 659是更快的 CPython 项目的关键部分之一。一般的想法是,虽然 Python 是一种动态语言,但大多数代码都有对象和类型很少更改的区域。这个概念被称为类型稳定性。

在运行时,Python 将尝试在执行代码中寻找通用模式和类型稳定性。然后 Python 将用更专业的操作替换当前操作。这种专门的操作使用仅适用于那些用例/类型的快速路径,这些用例/类型通常优于它们的通用对应物。这也引入了另一个称为内联缓存的概念,其中 Python 将昂贵操作的结果直接缓存在字节码中。

专门化程序还将某些公共指令对组合成一个超级指令。这减少了执行期间的开销。

Python 只有在看到“热”代码(多次执行)时才会专门化。这可以防止 Python 将时间浪费在运行一次的代码上。当代码过于动态或用途发生变化时,Python 也可以去专业化。定期尝试专业化,专业化尝试的成本也不会太高。这允许专业化以适应新的环境。

你可能感兴趣的:(Python新特性,python)