8 months, 3 weeks

Structural Pattern Matching




Structural pattern matching introduces a match statement and two new soft keywords: match and case. As the name suggests, it can be used to match a given value against a list of specified "cases" and act accordingly to the match.

Both match and case can be used as ordinary variables or function 
names outside the match statement context.

The general  syntax for a match statement is as follows:
match expression:                                                           
     case pattern:                                                               
     ...                                                                                 

expression can be any valid Python expression. pattern represents an actual matching pattern that is a new concept in Python. Inside a case block, you can have multiple statements.

First, we can use literals as patterns. Second, there is a special _ (underscore) wildcard pattern. Wildcard patterns and other patterns that, from the syntax alone, can be proven to match always create an irrefutable case block. An irrefutable case block can be placed only as the last block of a match statement.

for i in range(100):                                                               
     match (i % 3, i % 7):                                                       
          case (0, 0): print("The value is divisible by 3 and 7")
          case (0, _): print("The value is divisible by 3")          
          case (_, 0): print("The value is divisible by 7")          
          case _: print(i)                                                           

• The (0, 0) pattern: This will match a two-element sequence if both elements 
are equal to 0.


• The (0, _) pattern: This will match a two-element sequence if the first 
element is equal to 0. The other element can be of any value and type.


• The (_, 0) pattern: This will match a two-element sequence if the second 
element is equal to 0. The other element can be of any value and type.


• The _ pattern: This is a wildcard pattern that will match all values.

class Point:                                                                                     
   x: int                                                                                            
   y: int                                                                                            
   def __init__(self, x, y):                                                                
        self.x = x                                                                               
        self.y = y                                                                               
def where_is(point):                                                                     
     match point:                                                                            
         case Point(x=0, y=0):                                                         
              print("Origin")                                                                 
         case Point(x=0, y=y):                                                          
              print(f"Y={y}")                                                                 
         case Point(x=x, y=0):                                                         
              print(f"X={x}")                                                               
         case Point():                                                                    
              print("Somewhere else")                                           
         case _:                                                                           
              print("Not a point")                                                     

 

• Point(x=0, y=0): This matches if point is an instance of the Point class and 
its x and y attributes are equal to 0.


• Point(x=0, y=y): This matches if point is an instance of the Point class and 
its x attribute is equal to 0. The y attribute is captured to the y variable, which 
can be used within the case block.


• Point(x=x, y=0): This matches if point is an instance of the Point class and 
its y attribute is equal to 0. The x attribute is captured to the x variable, which 
can be used within the case block.


• Point(): This matches if point is an instance of the Point class.


• _: This always matches.

 

Match patterns can also use "positional attribute" syntax, but that requires a bit more work. You  need to provide an additional __match_args__ class attribute that specifies the natural position order of class instance attributes.

class Point:
   x: int
   y: int
   __match_args__ = ["x", "y"]
   def __init__(self, x, y):
     self.x = x
     self.y = y
def where_is(point):
    match point:
      case Point(0, 0):
         print("Origin")
      case Point(0, y):
         print(f"Y={y}")
      case Point(x, 0):
         print(f"X={x}")
      case Point():
         print("Somewhere else")
      case _:
         print("Not a point") 

 


Responses(0)







Related