Python 3.10 匹配/大小写与常量

mar*_*004 10 constants switch-statement python-3.x python-3.10

match/case我尝试用Python 3.10 中较短的代码块替换 if/elif/elif/.../else 代码块。我定义了三个常量,并希望对每个常量执行不同的操作,因此我的代码大致如下所示:

>>> const_a = 1
>>> const_b = 2
>>> const_c = 3
>>> interface = const_b  # example
>>> match interface:
...     case const_a:
...             print("case a")
...     case const_b:
...             print("case b")
...     case const_c:
...             print("case c")
Run Code Online (Sandbox Code Playgroud)

但是,运行这段代码时,会出现异常:

File "<stdin>", line 2
SyntaxError: name capture 'const_a' makes remaining patterns unreachable
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Pra*_*adi 5

match...case不仅仅是一个switch...case。来自https://www.python.org/dev/peps/pep-0622/#patterns

  • 捕获模式看起来像 x 并且相当于相同的赋值目标:它总是匹配并绑定具有给定(简单)名称的变量
  • 量值模式的工作方式与文字类似,但适用于某些命名常量。请注意,考虑到捕获模式可能存在歧义,它必须是限定(点)名称。它看起来像 Color.RED 并且仅匹配等于相应值的值。它永远不会绑定。

因此,您必须创建一个将这些变量作为属性的对象,并在匹配中使用限定名称

import types

consts = types.SimpleNamespace()
consts.A = 1
consts.B = 2
consts.C = 3

interface = 2

match interface:
    case consts.A:
        print("A")
    case consts.B:
        print("B")
    case consts.C:
        print("C")
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,打印B

有关原因的更多信息,请参阅https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern

  • 30 年来,人们一直在寻求像开关盒这样的东西。现在它终于实现了,如果没有这样的解决方法,你甚至无法将数字与常量匹配。如果没有这样的解决方法,对于这样一个常见且简单的用例来说失败了,谁会关心你可以用它做的所有高级模式匹配呢?老实说,这让我大吃一惊。 (15认同)