Structural Pattern Matching & Advanced Data Extraction
Introduced in PEP 634 (Python 3.10), Structural Pattern Matching (match/case) is a powerful control flow feature that combines structure matching, type inspection, sequence/mapping destructuring, and variable binding into a single declarative syntax.
This chapter details PEP 634 pattern types (Sequence, Mapping, Class, OR, AS), __match_args__ positional matching, pattern guards, and AST evaluation mechanics.
1. Structural Pattern Types Deep Dive (PEP 634)
Structural pattern matching evaluates a subject value against a series of case patterns:
Structural Pattern Matching Dispatch:
[ Subject Value (e.g. payload = {"type": "event", "data": [10, 20]}) ]
|
v
[ Case 1: Mapping + Sequence Pattern ]
{"type": "event", "data": [x, y]}
|
+---> Matches keys AND destructures [10, 20]!
| Binds: x = 10, y = 20
v
[ Execute Case Action Block ]Pattern Matching Taxonomy:
- Sequence Patterns (
case [x, y, *rest]:): Matches lists or tuples of specific lengths, capturing elements into variables and residual items into*rest. - Mapping Patterns (
case {"status": 200, "data": payload}:): Matches dictionary key structures without requiring the dictionary to be restricted to only those keys. - Class Patterns (
case Point(x=x, y=y):): Performsisinstance()checks and attribute extraction simultaneously. - OR Patterns (
case 401 | 403 | 404:): Matches any one of multiple alternative patterns. - AS Patterns (
case [x, y] as point:): Matches a sub-pattern while simultaneously binding the entire outer matched structure to a variable (point).
2. Class Positional Matching (__match_args__)
By default, Class patterns require keyword attribute matches (case Point(x=x, y=y):). To enable positional matching (case Point(x, y):), define __match_args__ on the target class:
class Point:
__match_args__ = ("x", "y") # Maps positional matches to attribute names!
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def process_shape(shape):
match shape:
# Uses __match_args__ to bind positional parameters x and y!
case Point(0, 0):
print("Origin Point")
case Point(x, y) if x == y: # Guard condition!
print(f"Diagonal Point at {x}")
case Point(x, y):
print(f"Point at ({x}, {y})")(Note: @dataclass classes automatically generate __match_args__ matching field definition order!).
3. Guard Expressions & Wildcards
- Guards (
case pattern if condition:): Adds a boolean condition evaluated after the pattern matches. If the guard evaluates toFalse, pattern matching continues to the nextcase. - Wildcard (
case _:): Matches any subject value without binding it to a variable (acts as the default fallback case).
4. Production Architectural Guidelines
- Use
match/casefor Heterogeneous API Payloads:match/caseshines when parsing complex, nested JSON responses, AST nodes, or event bus messages. - Avoid Soft Keyword Confusion:
matchandcaseare soft keywords. They are recognized as keywords only insidematchstatements;matchcan still be used as a standard variable name elsewhere in your codebase without breaking syntax.