[英]Invert a test with structural pattern matching
我一直在將 if-elif-chains 轉換為結構模式匹配,但在反向測試中遇到困難。
很容易創建匹配任何受支持模式(文字、class、映射、序列等)的案例。 我如何提出否定匹配的理由?
例如,當類型不匹配時,我需要強制轉換為 object:
if isinstance(x, (list, dict)):
x = json.dump(x)
elif not isinstance(x, str): # <-- Inverted test
x = str(x)
本質上,結構模式匹配的設計僅在存在正匹配時觸發案例。 但是,有兩種解決方法。
最簡單的方法是添加一個保護表達式。 但這是最后的手段,因為它沒有利用模式匹配和解構功能。
第二種方法是添加一個較早的匹配測試,以便后面的情況可以假定反向匹配為真。 如果否定案例是最后一個案例,那么這很好用。 如果不是,它會變得有點尷尬,因為需要嵌套。
進行倒置測試並將其移動到 if 表達式中:
match x:
case list() | dict():
x = json.dump(x)
case _ if not isinstance(x, str): # <-- Inverted test
x = str(x)
這里的基本思想是進行正匹配,以便后續案例可以假設為負匹配:
match x:
case list() | dict():
x = json.dump(x)
case str(): # <-- Positive match
pass
case _: # <-- Inverted case
x = str(x)
預測試技術很優雅,除非您有其他情況需要匹配:
if isinstance(x, (list, dict)):
x = json.dump(x)
elif not isinstance(x, str): # <-- Inverted test
x = str(x)
elif x == 'quit': # <-- Additional test
sys.exit(0)
這里最簡單的解決方案是將附加測試移動到倒置測試之前:
match x:
case list() | dict():
x = json.dump(x)
case 'quit': # <-- Moved the test up
sys.exit(0)
case str(): # <-- Positive match
pass
case _: # <-- Inverted case
x = str(x)
重新排序測試並不總是可能的。 如果是這樣,則可以引入新級別的嵌套匹配:
case list() | dict():
x = json.dump(x)
case str(): # <-- Positive match
match x: # <-- Nested match
case 'quit': # <-- Inner case
sys.exit(0)
case _: # <-- Inverted case
x = str(x)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.