提问人:Raymond Hettinger 提问时间:5/14/2021 更新时间:5/14/2021 访问量:460
避免在结构模式匹配中意外捕获
Avoiding accidental capture in structural pattern matching
问:
这个例子被讨论为使用模式匹配时可能出现的“陷阱”:
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 内置类型将替换为 x 的值。str
str()
是否有一种防御性编程实践可以帮助避免这些问题并提供早期检测?
答:
10赞
Raymond Hettinger
5/14/2021
#1
最佳实践
是否有一种防御性编程实践可以帮助避免这些问题并提供早期检测?
是的。通过始终包括 PEP 634 所描述的无可辩驳的案例块,可以很容易地检测到意外捕获。
用通俗的语言来说,这意味着一个始终匹配的包罗万象的情况。
运作方式
意外捕获始终匹配。不允许超过一个无可辩驳的案例块。因此,当添加有意捕获时,会立即检测到意外捕获。
修复第一个示例
只需在末尾添加一个包罗万象的通配符模式:
match retcode:
case NOT_FOUND:
print('not found')
case _:
pass
这会立即检测到问题,并给出以下错误:
SyntaxError: name capture 'NOT_FOUND' makes remaining patterns unreachable
修复第二个示例
在末尾添加一个包罗万象通配符模式:
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
评论