一篇文章带你快速盘点 python3.10 的新特性

一篇文章带你快速了解 python3.10 的新特性

python3.10 的预发布版已经出来了,今天和大家一起快速盘点一下 python3.10 中新增的哪些新的特性。

一、上下文管理器

python3.10 中,with 支持使用外层圆括号来使用多个上下文管理器,可以连续多行地书写。 这允许将过长的上下文管理器集能够以与之前 import 语句类似的方式格式化为多行的形式。 例如,以下这些示例写法现在都是有效的:

with (CtxManager() as example):
    pass

with (
    CtxManager1(),
    CtxManager2()
):
    pass

with (CtxManager1() as example,
      CtxManager2()):
    pass

with (CtxManager1(),
      CtxManager2() as example):
    pass

with (
    CtxManager1() as example1,
    CtxManager2() as example2
):
    pass

二、新增结构化模式匹配

python3.10 中新增的结构化模式匹配,主要由 matchcase 两个关键字实现,模式匹配的通用语法如下

status = 404

match status:
    case 400:
        res =  "Bad request"
    case 404:
        res =  "Not found"
    case 418:
        res =  "I'm a teapot"
    case _:
        res =  "Something's wrong with the internet"

match 语句接受一个表达式并将其值与以一个或多个 case 语句块形式给出的一系列模式进行比较。 具体来说,模式匹配的操作如下:

  1. 使用具有特定类型和形状的数据 (subject)
  2. 针对 subjectmatch 语句中求值
  3. 从上到下对 subject 与 case 语句中的每个模式进行比较直到确认匹配到一个模式。
  4. 执行与被确认匹配的模式相关联的动作。
  5. 如果没有确认到一个完全的匹配,则如果提供了使用通配符 _ 的最后一个 case 语句,则它将被用作已匹配模式。 如果没有确认到一个完全的匹配并且不存在使用通配符的 case 语句,则整个 match 代码块不执行任何操作。

三、新的类型联合运算符

python3.10 中引入了启用 X | Y 语法的类型联合运算符。 这提供了一种表示 '类型 X 或类型 Y' 的相比使用 typing.Union 更清晰的方式,特别是在类型提示中。在之前的 Python 版本中,要为可接受多种类型参数的函数应用类型提示。

def square(number: Union[int, float]) -> Union[int, float]:
    return number ** 2

类型提示现在可以使用更简洁的写法:

def square(number: int | float) -> int | float:
    return number ** 2

这个新增语法也被接受作为 isinstance()issubclass() 的第二个参数:

>>> isinstance(1, int | str)
True

四、类型别名

python3.10 中 引入了类型别名的概念,只要求它们是不带标注的最高层级赋值。 这种简单性有时会使得类型检查器难以区分类型别名和普通赋值,特别是当涉及到前向引用或无效类型的时候。

例如在比较:

StrCache = 'Cache[str]'  # a type alias
LOG_PREFIX = 'LOG[DEBUG]'  # a module constant

现在 typing 模块具有一个特殊值 TypeAlias 可让你更明确地声明类型别名:

StrCache: TypeAlias = 'Cache[str]'  # a type alias
LOG_PREFIX = 'LOG[DEBUG]'  # a module constant

五、错误信息更详细

5.1、SyntaxError

在 python3.10 之前代码中的语法错误,大都错误提示信息都不精准,在 python3.10 中做了更多的优化处理,

一、缺少括号的错误提示更完善

在 3.10 之代码如果你写的代码中缺少一个括号,运行代码抛出的错误信息中并不会准备的提示你哪个位置缺少括号,而是抛出一个不准确的错误信息。如下

a = {9: 1, 18: 2, 19: 2
b = 100
python3.10 之前:
File "demo.py", line 3
    b = 100
      ^
SyntaxError: invalid syntax

但在 Python 3.10 中则提示更准确的错误信息:

python3.10:
File "demo.py", line 1
    a = {9: 1, 18: 2, 19: 2
                            ^
SyntaxError: '{' was never closed
二、语法错误的代码高亮标识
3.10 之前的语法错误显示
>>> foo(x, z for z in range(10), t, w)
  File "<stdin>", line 1
    foo(x, z for z in range(10), t, w)
           ^
SyntaxError: Generator expression must be parenthesized
3.10 的语法错误显示
>>> foo(x, z for z in range(10), t, w)
  File "<stdin>", line 1
    foo(x, z for z in range(10), t, w)
           ^^^^^^^^^^^^^^^^^^^^
SyntaxError: Generator expression must be parenthesized
三、更多详细的错误提示场景
代码块之前缺失 :
>>> if rocket.position > event_horizon
  File "<stdin>", line 1
    if rocket.position > event_horizon
                                      ^
SyntaxError: expected ':'
在多项集字面值中和表达式之间缺失逗号: :
>>> items = {x: 1,y: 2 z: 3}
  File "<stdin>", line 3
    y: 2
       ^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
多个异常类型捕获时不带圆括号:
>>> try:
...     build_dyson_sphere()
... except NotEnoughScienceError, NotEnoughResourcesError:
  File "<stdin>", line 3
    except NotEnoughScienceError, NotEnoughResourcesError:
           ^
SyntaxError: multiple exception types must be parenthesized
字典字面值中缺失 : 和值:
>>> values = {x: 1,y: 2,z:}
  File "<stdin>", line 4
    z:
     ^
SyntaxError: expression expected after dictionary key and ':'

>>> values = {x:1, y:2, z w:3}
  File "<stdin>", line 1
    values = {x:1, y:2, z w:3}
                        ^
SyntaxError: ':' expected after dictionary key
在比较中使用 = 而不是 ==
>>> if rocket.position = event_horizon:
  File "<stdin>", line 1
    if rocket.position = event_horizon:
                       ^
SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='?
try 代码块不带 exceptfinally 代码块:
>>> try:
...     x = 2
... something = 3
  File "<stdin>", line 3
    something  = 3
    ^^^^^^^^^
SyntaxError: expected 'except' or 'finally' block

5.2、IndentationError

代码缩进异常的意识更完善,会明确提示需要缩进的语句,包括语句的位置:

>>> def foo():
...    if lel:
...    x = 2
  File "<stdin>", line 3
    x = 2
    ^
IndentationError: expected an indented block after 'if' statement in line 2

5.3、AttributeError

当打印 AttributeError 时,将提供引发异常的对象中类似属性名称的建议:

>>> collections.namedtoplo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'collections' has no attribute 'namedtoplo'. Did you mean: namedtuple?

5.4、NameError

NameError 的错误信息中将提供引发异常的函数中类似变量名称的建议

>>> schwarzschild_black_hole = None
>>> schwarschild_black_hole
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'schwarschild_black_hole' is not defined. Did you mean: schwarzschild_black_hole?

六、其他语言特性修改

1 操作
nmb_musen 在 2021-09-17 21:19:09 更新了该帖
回帖
请输入回帖内容 ...