Mastering Structural Pattern Matching in Python 3.10
Overview of Structural Pattern Matching
switch-case statements found in if-elif-else blocks, making it both more readable and less prone to errors when dealing with varied input formats.
Prerequisites
To follow this guide, you should have a solid grasp of match and case keywords were not available in previous versions.
Key Libraries & Tools
- shlex: A standard library module used for splitting strings into tokens, specifically designed for command-line syntax parsing.
- dataclasses: Used to create concise data-holding classes that work seamlessly with pattern matching.
- pyenv: A tool for managing multiple Python versions, useful for testing newer features like 3.10.
Code Walkthrough: Parsing Commands
Let's look at how we can use matching to build a robust command-line interface. First, we'll implement a sophisticated match that handles multiple keywords and variable arguments.
import shlex

def run_command(command_str): # Split input while respecting quotes split_cmd = shlex.split(command_str)
match split_cmd:
case ["quit" | "exit" | "bye", *rest] if "--force" in rest:
print("Force quitting...")
return False
case ["quit" | "exit" | "bye", *rest]:
print("Quitting normally.")
return False
case ["load", filename]:
print(f"Loading: {filename}")
case _:
print(f"Unknown command: {command_str}")
return True
In this snippet, we use the `|` (OR) operator to match multiple exit commands in a single line. The `*rest` syntax captures any additional arguments into a list. Notice the **guard condition** (`if "--force" in rest`), which allows us to filter the match based on external logic.
## Pattern Matching with Objects
One of the most powerful aspects is matching against class attributes. By using [dataclasses](entity://libraries/dataclasses), we can match specific object structures.
```python
from dataclasses import dataclass
@dataclass
class Command:
action: str
args: list
def process_obj(cmd: Command):
match cmd:
case Command(action="load", args=[filename]):
print(f"Object match: Loading {filename}")
case Command(action="quit", args=["--force", *_]):
print("Object match: Force quit detected.")
This syntax verifies that the object is an instance of Command and checks specific attribute values simultaneously. It is significantly cleaner than multiple isinstance and getattr calls.
Syntax Notes
- The Underscore (_): This acts as a wildcard, matching anything without binding it to a variable. It is standard for the default case.
- Binding Variables: When you use a name like
filenamein a case, Python automatically assigns the matched value to that variable for use inside the case block.
Tips & Gotchas
Order is critical. Python checks cases from top to bottom and stops at the first match. If you put a broad pattern (like case [*rest]) above a specific one (like case ["load", name]), the specific one will never execute. Always place your most specialized patterns at the top and your most generic catch-alls at the bottom.

Fancy watching it?
Watch the full video and context