了解模式匹配的用例
#编程 #教程 #python #softwaredevelopment

模式匹配终于自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定义进行比较。

从代码中我们可以看到模式匹配使比较条件变得简单,但这不是模式匹配的幂,因为我们尚未比较嵌套的结构。让我们看下一个示例。

解析树

假设现在我想在具有多种颜色和形状的二进制树上找到一些图案。

给出了这样的树,我想知道:

  • 树上有一个绿色正方形,左节点附有红色圆圈?
  • 树是否具有任何颜色的形状,左节点附有一个黄色的三角形,右节点附有蓝色矩形?
  • 树有一个黄色圆圈,左节点附有一个蓝色矩形。对于蓝色矩形,左节点连接到红色三角形,右节点连接到红色矩形。红色矩形,右节点连接到绿色广场。

然后我们的思维模型看起来像以下图。

Image description

实际上,这就是我们的所有程序。

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的代码。

结论

模式匹配是一种强大的技术,它不仅是简单的if-elseswitch-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')

我相信大多数人不这么认为,这是一个典型的误用场景。

总结一下,使用模式匹配的场景不是有条件的比较,而是模式比较。另外,图案匹配的真正力量是嵌套结构。

参考