首页 > 解决方案 > 如果先前未定义变量,为什么匹配案例语句会分配给其中一种情况中使用的变量?

问题描述

在学习 Python 10 中引入的模式匹配时,我遇到了一个示例,其中一部分拆分字符串被分配/绑定到其中一种情况下使用的变量。

match 'make dir'.split():
    case ["make"]:
       print("default make")
    case ["make", cmd]:
       print(f"make command found: {cmd}"}
    case ["restart"]:
       print("restarting")
    case ["rm", *files]:
       print (f"deleting files: {files}")
    case _:
       print("didn't match")

第二种情况有先前未声明的变量cmd,它最终被赋值"dir"

标签: pythonstructural-pattern-matching

解决方案


在模式["make", cmd]中,cmd是一种捕获模式。捕获模式(看起来像不带点的名称,例如foobarcmd)匹配任何东西,并将匹配的值无条件地绑定到该名称。

在您的示例中,以 2 开头的任何长度序列"make"都会将第二个元素绑定到cmd并执行第二个case块。这很有用,因为它允许您的应用程序轻松确定make应该执行哪个命令。

cmd无论是否已分配,都会发生这种情况。因此,如果它已经被绑定,那么旧值将被新的匹配值覆盖。

如果您想按值比较名称,则根据您的情况有几种选择:

  • 如果名称带有点(如args.cmdClass.VAR),它将自动按相等比较(而不是捕获)。因此,您可以将["make", args.cmd]其用作您的模式。

  • 如果名称是空的(如cmdor VAR),您可以使用捕获模式和保护来通过相等性进行比较。使用这种技术,您的模式可能看起来像["make", c] if c == cmd. 请注意,由于c是一个捕获模式,它将像cmd您原来的示例一样被反弹!(随着您更多地使用模式匹配,您会发现捕获模式 likec在执行更复杂的模式匹配时非常有用。)

我建议任何想要熟悉 Python 的结构模式匹配的人查看官方教程。它以非常易于理解的方式涵盖了所有不同的模式(包括捕获模式)。


推荐阅读