2021 年 10 月 4 日,Python 3.10 发布。match-case
在其他更新中,使用称为结构模式匹配的构造的能力或pattern matching
如何使用这个设计?
对于早期版本的 Python,请参阅此 ruSO 答案中的实现(类似于 switch-case 构造)。
2021 年 10 月 4 日,Python 3.10 发布。match-case
在其他更新中,使用称为结构模式匹配的构造的能力或pattern matching
如何使用这个设计?
对于早期版本的 Python,请参阅此 ruSO 答案中的实现(类似于 switch-case 构造)。
Python 3.10 引入了模式匹配
本资料是文章《如何在 Python 中使用结构模式匹配》的翻译
Python 3.10 的新版本引入
case/match
了负责在语言中实现模式匹配语法的运算符。尽管 Python 简单且受欢迎,但与其他语言不同,它没有单独的流控制形式——一种获取值并优雅地将其与许多可能条件之一匹配的方法。在 C 和 C++ 中,这个特性是由结构实现的
switch/case
,而在 Rust 中,它被称为模式匹配。到目前为止,除了使用构造
if/elif/else
和字典查找之外,在 Python 中还没有优雅的方法来做到这一点。这两种方法都有效,但由于它们的体积庞大,它们可能使代码更难阅读。多年来,已经多次尝试
switch/case
在 Python 中包含类型语法,但都失败了。这是结构模式匹配的第一个实现,目前仅在开发人员版本中可用。(请注意,从 version 开始,每个人都可以使用该实现python 3.10
)Python中的模式匹配简介
结构模式匹配引入了一个
match/case
与switch/case
. 操作员根据一个或多个模式检查对象,如果找到匹配项,则执行操作。每个表达式
case
后跟一个要匹配的模式。在这个例子中,字符串与操作符从上到下匹配,如果找到这样的匹配,则执行操作符。也可以捕获全部或部分匹配并重新使用它。在我们的示例中,在模式匹配的情况下,unknown_command
我们在 f-string中重用了它。变量匹配与模式匹配
如果要将值映射到常量,则应将常量称为类的字段:
如果您尝试在不求助于课程的情况下做到这一点,如下所示:
获取与名称不属于已知模式相关的错误响应:
使用模式匹配匹配多个元素
模式匹配不仅用作字典查找的替代品。它用于描述您想要匹配的内容的结构。因此,您可以根据要匹配的项目数或它们的组合来执行匹配。
这是一个更复杂的例子。在这里,用户输入一个命令,可能后跟一个文件名:
让我们按顺序查看案例选项:
case [’quit’]:
检查我们匹配的内容是否仅与列表与’quit’
将输入拆分后获得的元素匹配split()
。case [’load’, filename]:
检查第一个分隔元素是否为字符串’load’
,以及它后面是否跟着第二个字符串。如果有第二行,则将第二行存储在变量中filename
并用于进一步的工作。以同样的方式检查case [«save», filename]:
。case _:
这是通配符匹配。如果在该点之前没有发生其他匹配,则发生匹配。请注意,下划线字符 (_
) 不与任何内容相关联,在这种情况下,下划线用作命令的信号,match
即所讨论的大小写是通配符。(这就是我们在块体中引用命令变量的原因case
,因为没有捕获任何内容。)结构模式匹配中的模式
模板可以是简单的值,也可以包含更复杂的匹配逻辑。
这里有些例子:
case ’a’:
匹配单个值’a’
。case [’a’,’b’]:
映射到一个集合(collection)[’a’,’b’]
。case [’a’, value1]:
映射到具有两个值的集合,并将第二个值放入变量value1
中。case [’a’, *values]:
映射到至少有一个值的集合。剩余值(如果有)存储在values
. 请注意,每个模板只能包含一个带有星号的元素。case (’a’|’b’|’c’):
运算符or
,也称为|
,可用于在单个案例块中处理多个调用。这里我们匹配’a’
,’b’
, 或’c’
。case (’a’|’b’|’c’) as letter:
和上面一样,只是我们现在把对应的元素放在letter
.case [’a’, value] if ...:
只有当表达式为真时,该变量才被绑定。我们要绑定的变量可以在...
. 例如,如果我们使用if value in valid_values
,那么case
只有在捕获的值实际上在valid_values
.case [’z’, _]:
将匹配任何以 . 开头的元素集合’z’
。使用模式匹配与对象匹配
Python 中最先进的模式匹配功能是能够匹配具有特定属性的对象。考虑一个我们正在使用的应用程序
media_object
。我们想将此对象转换为文件.jpg
并从函数中返回。在上面的每一个中
case
,我们都在寻找某种类型的对象,有时具有某些属性。Image
在第一种情况下,我们正在寻找type
属性为的对象的匹配项’jpg’
。如果 type 匹配,则第二case
个匹配’png’
or’gif’
。在第三case
个中,检查对象是否符合 typeVideo
,而属性没有值。在最后一种情况下,我们得到了之前没有选择的所有内容。您还可以使用对象匹配进行捕获:
有效使用模式匹配
使用
match/case
Python 的关键是编写描述您想要使用的结构的模板。简单的常量测试很好,但如果这就是你所做的一切,最好只做一个字典查找。Python 中结构模式匹配的真正价值在于能够匹配对象的模式,而不仅仅是任何一个对象,甚至是它们的集合。要记住的另一个重要细节是映射的写入顺序。您首先检查的匹配将影响您的整体匹配的有效性和准确性。首先放置最具体的比较,最后放置最一般的比较。
最终,如果您有一个可以通过
if/elif/else
或字典查找解决的问题,那么请使用它们而不是match/case
. 模式匹配很强大,但不是通用的。在最有意义的时候使用它。您可以在此处阅读有关 Python (PEP 622) 中的模式匹配文档的更多信息。
原创文章。