2

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")

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

File "<stdin>", line 2
SyntaxError: name capture 'const_a' makes remaining patterns unreachable

我究竟做错了什么?

4

2 回答 2

1

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")

正如预期的那样,打印B

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

于 2021-04-20T15:19:04.033 回答
-2

[这个答案是假设的]

FWIW,这就是我完成匹配/案例的方式 - 对我来说似乎比从头开始获取新变量并且没有聪明的可能性使用变量来比较或实际常量更直观:

替代匹配/案例提案


SOME_CONSTANT = 0
some_string = "qwert"

def example_matchcase (var):
    
    match var
        
    # simple literal case
    case 10:
        print("case 1")
    
    # basic check including another variable
    case len(some_string):
        print("case 2")
    
    # check against a constant
    case SOME_CONSTANT:
        print("case 3")
    
    # if-like statement
    case ? 0 < var < 10:
        print("case 4")
    
    case ? callable(var):
        print("case 5")
    case ? hasattr(var, 'isnumeric') and var.isnumeric():
        print("case 6")
    
    # slide statement
    case ? var < 50:
        print("case 7a")
        slide
    case ? var < 25:
        print("case 7b")
        slide
    case ? var < 10:
        print("case 7c")
        slide
    
    case ? var in (1,3,5,7):
        print("case 8 - early prime:", var)
    
    # 'else' instead of 'case _:'
    # more meaningful, _ looks like an unused variable and potentially conflicts with gettext
    else:
        print("unknown value")


""" real-world example where this would be very elegant """

INTERF_MUPDF = 0
INTERF_PDFIUM = 1
INTERF_POPPLER = 2

def render_thumbnails (interface):
    match interface
    case INTERF_MUPDF:
        from interfaces import InterfMupdf
        _interface = InterfMupdf()
    case INTERF_PDFIUM:
        from interfaces import InterfPdfium
        _interface = InterfPdfium()
    case INTERF_POPPLER:
        from interfaces import InterfPoppler
        _interface = InterfPoppler()
    case ? callable(interface):
        print("using a custom interface")
        _interface = interface
    else:
        raise Exception("`interface` must be a constant or a callable object")

于 2021-04-20T17:58:20.213 回答