簡體   English   中英

使用結構模式匹配反轉測試

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM