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:

  1. Sequence Patterns (case [x, y, *rest]:): Matches lists or tuples of specific lengths, capturing elements into variables and residual items into *rest.
  2. Mapping Patterns (case {"status": 200, "data": payload}:): Matches dictionary key structures without requiring the dictionary to be restricted to only those keys.
  3. Class Patterns (case Point(x=x, y=y):): Performs isinstance() checks and attribute extraction simultaneously.
  4. OR Patterns (case 401 | 403 | 404:): Matches any one of multiple alternative patterns.
  5. 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 to False, pattern matching continues to the next case.
  • Wildcard (case _:): Matches any subject value without binding it to a variable (acts as the default fallback case).

4. Production Architectural Guidelines

  • Use match/case for Heterogeneous API Payloads: match/case shines when parsing complex, nested JSON responses, AST nodes, or event bus messages.
  • Avoid Soft Keyword Confusion: match and case are soft keywords. They are recognized as keywords only inside match statements; match can still be used as a standard variable name elsewhere in your codebase without breaking syntax.
Display Options
Appearance
Text Size
100%