如果先前未定义变量,为什么 match-case 语句会分配给在其中一种情况下使用的变量?

Why does a match-case statement assign to a variable used in one of the cases if the variable was not previously defined?

在学习 Python 10 中介绍的模式匹配时,我遇到了一个示例,其中拆分字符串的一部分被 assigned/bound 到其中一个案例中使用的变量。

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"

在模式 ["make", cmd] 中,cmd 是一个 捕获模式 。捕获模式(看起来像 foobarcmd 等未加点的名称)匹配 anything,并无条件地绑定匹配的值那个名字。

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

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

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

  • 如果名称是带点的(如args.cmdClass.VAR),它会自动相等比较(而不是捕获).所以你可以只使用 ["make", args.cmd] 作为你的模式。

  • 如果名字是空的(如cmdVAR),你可以使用捕获模式和guard以平等来比较。使用这种技术,您的模式可能看起来像 ["make", c] if c == cmd。请注意,由于 c 是一个捕获模式,它会像 cmd 在您的原始示例中一样被反弹! (当你更多地使用模式匹配时,你会发现像 c 这样的捕获模式在执行更复杂的模式匹配时非常有用。)

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