What is Structural Pattern Matching? |
structural pattern matching allows checking a value against a pattern extract parts of the value if the pattern matches can make complex conditionals simpler and more readable basic syntax # -> str indicates the function returns a string def http_status(status: int) -> str: match status: case 200: return "OK" case 404: return "Not Found" case 500: return "Internal Server Error" case _: return "Unknown Error"patterns can range from simple constants to more complex structures |
Constant Patterns |
constant patterns match literal values the underscore (_) is typically used as a placeholder when a particular value isn't important _ used as default case below value = 42 match value: case 0: print("Zero") case 3.14: print("Pi") case 42: print("The answer to life, the universe, and everything") case "Some Name": print("Hello") case _: print("Something Else") |
Variable Patterns |
variable patterns capture the matched value when matching instances of any type, need to match against an object pattern use the type_name() syntax similar to instantiating an object value = 42 match value: case int() as i: print(f"Got an int variable: {i}") case float() as f: print(f"Got a float variable: {f}") case str() as s: print(f"Got a str variable: {s}") case unknown: print(f"Got an unknown object: unknown") |
Sequence Patterns |
sequence patterns match against lists, tuples, and other sequences
data = [1, 2, 3] match data: case [1, 2, 3]: print("Matched [1, 2, 3]") case [1, 2, _]: print("Matched [1, 2, _]") case [int(), int(), int()]: print("Matched [int(), int(), int()]") case _ : print("No match") |
Mapping Patterns |
mapping patterns match against dictionaries will only match against the keys defined in the match statement ignores other keys config = {"host": "localhost", "port": 8080, "token": " |
Conditional Patterns |
patterns can match objects with optional extra evaluation
status = 404 match status: case int() if 0 <= status < 100: print("Informational") case int() if 100 <= status < 200: print("Success") case int() if 200 <= status < 300: print("Redirection") case int() if 300 <= status < 400: print("Client Error") case int() if 400 <= status < 500: print("Server Error") case _: print("Unknown error code") |
Combining Patterns |
patterns can be combined using | (OR)
status = 200 match status: case 200 | 201: print("Success") case 400 | 404: print("Client Error") case _: print("Other Error") |
Add Matching to Custom Objects |
to enable pattern matching on custom objects need to implement certain dunder methods in the classes these methods help the match statement understand how to destructure the objects the __match_args__ attribute is a tuple that specifies the attribute names for pattern matching by default it's an empty tuple and no attributes can be extracted class Point: __match_args__ = ("x", "y") def __init__(self, x, y): self.x = x self.y = y point = Point(10, 20) match point: case Point(10, 20): print("Home") case Point(x, y): print(f"Point with {x=}, {y=}") case _: print("Unknown Position") |