模式匹配终于自3.10起就在Python中得到了支持,并且此功能对许多功能性编程语言来说是常见的,它已被无痛地移植到Python。
但是,对于我们这些新手匹配的人来说if-else
允许对变量进行更细粒度的定义。
要了解模式匹配的真实用例,我们必须在PEP 635中查看段落。
模式匹配的大部分力量来自子图案的嵌套。因此,模式匹配的成功直接取决于Subpattern的成功是设计的基石。
subpatterns的嵌套听起来有些抽象,该属性的一些实际示例是什么?
最简单的数据结构是树。
以二进制树为例,从顶部到底部穿越,每个节点实际上满足以下属性。
class TreeNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
每个节点将具有自己的属性,以及左右的孩子,这是典型的嵌套结构。因此,最实际的例子之一是寻找满足图案的树节点。
ast树
ast树是一种非常常见的方法,用于棉或语法检查。
假设我们需要检查源代码是否直接调用print
,然后我们可以使用if
比较条件并找出满足条件的节点是否违反了毛刺规则。
for node in ast.walk(tree):
if (
isinstance(node, ast.Call) # It's a call
and isinstance(node.func, ast.Name) # It directly invokes a name
and node.func.id == 'print' # That name is `print`
):
sys.exit(0)
sys.exit(1)
从上面的代码中,我们知道我们要匹配节点ast.Call
,它是一个呼叫函数,函数名称是打印的,总共三个条件。
现在,我们知道要比较的模式条件,让我们按照图案匹配如下重写。
for node in ast.walk(tree):
match node:
# If it's a call to `print`
case ast.Call(func=ast.Name(id='print')):
sys.exit(0)
sys.exit(1)
通过模式匹配,我们可以通过将条件与我们的脑海中的class
定义进行比较。
从代码中我们可以看到模式匹配使比较条件变得简单,但这不是模式匹配的幂,因为我们尚未比较嵌套的结构。让我们看下一个示例。
解析树
假设现在我想在具有多种颜色和形状的二进制树上找到一些图案。
给出了这样的树,我想知道:
- 树上有一个绿色正方形,左节点附有红色圆圈?
- 树是否具有任何颜色的形状,左节点附有一个黄色的三角形,右节点附有蓝色矩形?
- 树有一个黄色圆圈,左节点附有一个蓝色矩形。对于蓝色矩形,左节点连接到红色三角形,右节点连接到红色矩形。红色矩形,右节点连接到绿色广场。
然后我们的思维模型看起来像以下图。
实际上,这就是我们的所有程序。
def Find(Tree):
match Tree:
case Square('green' ,
Circle('red') as left ,
_
) as root:
print(f'case1 \n {root = } \n {left = } \n ')
case Geometric( _ ,
Triangle('yellow') as left,
Rectangle('blue') as right,
):
print(f'case2 \n {left = } \n {right = } \n')
case Circle('yellow',
_ ,
Rectangle('blue',
Triangle('red'),
Rectangle('red',
_ ,
Square('green')
),
) as right
) as root:
print(f'case3 \n {root = } \n {right = } \n ')
case _:
print('Not Found \n')
在此示例中,我们可以看到模式匹配的力量,不仅可以比较与情况2的模糊条件进行比较,还可以比较模糊条件2。我们直接掌握了代码。
实际上,数据库和大数据引擎优化器大量使用模式匹配(不是在Python中),因为优化器需要匹配的模式是如此复杂,以至于很难维护仅使用if-else
的代码。 P>
结论
模式匹配是一种强大的技术,它不仅是简单的if-else
或switch-case
,而且是“模式匹配”。
但是,在我们的日常生活中,我们很少会真正利用模式匹配的力量,这既是因为我们很少处理大量嵌套结构,并且因为我们误解了应用于它们的场景。
这是Stack Overflow的经典示例。我用最喜欢的人捕获了答案。
match a:
case _ if a < 42:
print('Less')
case _ if a == 42:
print('The answer')
case _ if a > 42:
print('Greater')
这真的比if-else
好吗?
if a < 42:
print('Less')
elif a == 42:
print('The answer')
elif a > 42:
print('Greater')
我相信大多数人不这么认为,这是一个典型的误用场景。
总结一下,使用模式匹配的场景不是有条件的比较,而是模式比较。另外,图案匹配的真正力量是嵌套结构。
参考