| 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")
|