Python 3.10 版本具有多项新功能,例如结构模式匹配、新的类型联合运算符和带括号的上下文管理器!
Python 3.10 的开发已经稳定下来,我们终于可以测试最终版本中将包含的所有新功能。
我们将介绍 Python 中最有趣的一些新增功能 - 结构模式匹配、带括号的上下文管理器、更多类型以及新的和改进的错误消息。
点击跳转:详细介绍
结构模式匹配
这是 Python 3.10 最受期待的特性。这个特性引入了一个类似switch/case的特性,就像我们在 Python 的其他编程语言中一样。除了类似 switch 的特性,Python 3.10 Structural Pattern Matching 还带来了一些额外的特性,使其比通常的 switch 条件语句更强大。
它以 匹配语句 和 带有关联操作的模式的case语句的形式添加。模式由序列、映射、原始数据类型以及类实例组成。
模式匹配的通用语法是:
match subject:
case <pattern_1>:
<action_1>
case <pattern_2>:
<action_2>
case <pattern_3>:
<action_3>
case _:
<action_wildcard>
match 语句采用表达式并将其值与作为一个或多个 case 块给出的连续模式进行比较。具体来说,模式匹配通过以下方式运作:
- 使用具有类型和形状的数据 (the subject)
- 评估 subject 的 match 声明
- case 从上到下将主题与语句中的每个模式进行比较, 直到确认匹配为止。
- 执行与确认匹配的模式相关联的操作
- 如果未确认完全匹配,则最后一种情况,通配符 _(如果提供)将用作匹配情况。如果未确认完全匹配且不存在通配符大小写,则整个匹配块为空操作。
让我们把这个例子看作是最简单形式的模式匹配:一个值,主题,与几个文字匹配,模式。在下面的示例中, status 是 match 语句的主题。模式是每个 case 语句,其中文字表示请求状态代码。匹配后执行与案例相关的操作:
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the Internet"
如果上述函数传递了status 418 的a ,则返回“我是茶壶”。如果上面的函数传递了 status 500 的 a,case 语句 with _ 将作为通配符匹配,并返回“Internet 出现问题”。请注意最后一个块:变量名称 , _充当 通配符 并确保主题始终匹配。的使用 _ 是可选的。
您可以使用| (“or”)在单个模式中组合多个文字 :
case 401 | 403 | 404:
return "Not allowed"
带括号的上下文管理器
现在支持使用括号在上下文管理器中跨多行继续。这允许以类似于以前使用 import 语句可能的方式在多行中格式化一长串上下文管理器。
with (CtxManager() as example):
...
with (
CtxManager1(),
CtxManager2()
):
...
with (CtxManager1() as example,
CtxManager2()):
...
with (CtxManager1(),
CtxManager2() as example):
...
with (
CtxManager1() as example1,
CtxManager2() as example2
):
...
也可以在封闭组的末尾使用尾随逗号:
with (
CtxManager1() as example1,
CtxManager2() as example2,
CtxManager3() as example3,
):
...
更好的错误信息
在以前版本的 Python 中,由于错误消息不佳,调试代码非常困难。解析器从以前版本的 Python 生成的错误消息不是特定的。这个版本带来了更精确的信息。
语法错误
当解析包含未闭合括号或括号的代码时,解释器现在包括括号未闭合括号的位置,而不是在解析 或指向某些不正确的位置时显示 SyntaxError:unexpected EOF。例如,考虑以下代码(注意未闭合的“{”):
expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
38: 4, 39: 4, 45: 5, 46: 5, 47: 5, 48: 5, 49: 5, 54: 6,
some_other_code = foo()
先前版本的解释器将令人困惑的地方报告为语法错误的位置:
File "example.py", line 3
some_other_code = foo()
^
SyntaxError: invalid syntax
但在 Python 3.10 中,会发出更多信息错误:
File "example.py", line 1
expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
^
SyntaxError: '{' was never closed
以类似的方式,涉及未闭合字符串文字(单引号和三引号)的错误现在指向字符串的开头,而不是报告 EOF/EOL。
缩进错误
许多 IndentationError 异常现在有更多关于期望缩进的块类型的上下文,包括语句的位置:
def foo():
if lel:
x = 2
File "<stdin>", line 3
x = 2
^
IndentationError: expected an indented block after 'if' statement in line 2
属性错误
打印时 AttributeError, PyErr_Display() 将提供引发异常的对象中类似属性名称的建议:
collections.namedtoplo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'collections' has no attribute 'namedtoplo'. Did you mean: namedtuple?
名称错误
当打印 NameError 由解释器引发时, PyErr_Display() 将在引发异常的函数中提供类似变量名称的建议:
>>> 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?
新型联合运算符
大多数人可能知道 Pythn 支持类型提示。它们不保证类型安全,但可作为开发中的有用工具。
引入了一种新的类型联合运算符,它启用了语法 X | Y。这提供了一种更清晰的方式来表达“X 型或 Y 型”而不是使用 typing.Union,尤其是在类型提示中。
在以前版本的 Python 中,为了对接受多种类型参数的函数应用类型提示, typing.Union 使用了:
def square(number: Union[int, float]) -> Union[int, float]:
return number ** 2
现在可以用更简洁的方式编写类型提示:
def square(number: int | float) -> int | float:
return number ** 2
这种新语法也被接受为isinstance() and 的第二个参数 issubclass():
>>> isinstance(1, int | str)
True
其他语言更改
- 该 int 类型有一个新方法 int.bit_count(),返回给定整数的二进制展开式中 1 的数量,也称为人口计数。
- 该 zip() 函数现在有一个可选 strict 标志,用于要求所有可迭代项具有相等的长度。
- 现在可以将变量声明为类型别名,以允许前向引用、更可靠的涉及类型的错误以及更好地区分范围内的类型声明。
- 现在需要 OpenSSL 1.1.1 或更新版本来构建 CPython。这使 CPython 的关键依赖项之一现代化。