【问题标题】:Avoiding accidental capture in structural pattern matching避免结构模式匹配中的意外捕获
【发布时间】:2021-08-04 03:17:13
【问题描述】:

This example 在使用模式匹配时被认为可能是“陷阱”:

NOT_FOUND = 400

retcode = 200
match retcode:
    case NOT_FOUND:
        print('not found')  

print(f'Current value of {NOT_FOUND=}')

这是使用结构模式匹配意外捕获的示例。它给出了这个意想不到的输出:

not found
Current value of NOT_FOUND=200

同样的问题以其他形式出现:

match x:
    case int():
        pass
    case float() | Decimal():
        x = round(x)
    case str:
        x = int(x)

在本例中,str 需要有括号,str()。没有它们,它会“捕获”并且 str 内置类型被替换为 x 的值。

是否有defensive programming 实践可以帮助避免这些问题并提供早期检测?

【问题讨论】:

    标签: python defensive-programming python-3.10 structural-pattern-matching


    【解决方案1】:

    最佳实践

    是否有一种防御性编程实践可以帮助避免这些问题并提供早期检测?

    是的。通过始终包含 PEP 634 描述为 irrefutable case block 的内容,可以轻松检测到意外捕获。

    用简单的语言来说,这意味着总是匹配的包罗万象的大小写。

    工作原理

    意外捕获始终匹配。不允许超过一个无可辩驳的案例块。因此,当添加有意的包罗万象时,会立即检测到意外捕获。

    修正第一个例子

    只需在末尾添加一个笼统的wildcard pattern

    match retcode:
        case NOT_FOUND:
            print('not found')
        case _:
            pass
    

    立即检测到问题并给出以下错误:

    SyntaxError: name capture 'NOT_FOUND' makes remaining patterns unreachable
    

    修正第二个例子

    在末尾添加一个笼统的wildcard pattern

    match x:
        case int():
            pass
        case float() | Decimal():
            x = round(x)
        case str:
            x = int(x)
        case _:
            pass
    

    再次立即检测到问题:

    SyntaxError: name capture 'str' makes remaining patterns unreachable
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2021-05-04
      相关资源
      最近更新 更多