Back to Blog
Python

Python Capture Pattern: Syntax and Usage

python capture pattern: Learn how Python capture patterns bind variables inside match statements, with practical examples of sequence, class, and wildcard patterns.

pythonstructural pattern matchingmatch statementcapture pattern
Illustration of Python capture pattern binding a value from a match statement to a variable.

Python's structural pattern matching, introduced in Python 3.10, includes capture patterns that bind matched values to variable names. A capture pattern looks like a bare name inside a case clause, such as case x:. When the pattern matches, Python assigns the subject value to that name, making it available in the case body. The python capture pattern syntax is straightforward, but its behavior has subtle implications for variable binding and pattern ordering.

Basic Syntax and Binding Behavior

A capture pattern is simply a name that appears in a pattern. For example:

match command: case "start": print("Starting") case other: print(f"Unknown command: {other}")

Here, other is a capture pattern. It matches any value and binds that value to the variable other. The variable is scoped to the case block. Unlike assignment, the capture pattern does not require the variable to exist beforehand.

Capture patterns can appear anywhere a pattern is allowed: in sequence patterns, mapping patterns, class patterns, and as the subject of a wildcard. The key property is that the name receives the matched value.

Capturing Multiple Values in Sequence Patterns

Sequence patterns allow you to capture individual elements. For example:

point = (3, 4) match point: case (x, y): print(f"x={x}, y={y}")

Here, x and y are capture patterns that bind to the first and second elements of the tuple. The pattern requires exactly two elements; if the sequence has a different length, the case does not match. You can combine capture patterns with literal values:

match point: case (0, y): print(f"On y-axis at y={y}") case (x, 0): print(f"On x-axis at x={x}") case (x, y): print(f"Point at ({x}, {y})")

This lets you extract values while still enforcing specific structure.

Using Capture Patterns with Class Patterns

Class patterns match against an object's type and can capture attributes. For example:

class Point: def __init__(self, x, y): self.x = x self.y = y match obj: case Point(x=x_val, y=y_val): print(f"Point at ({x_val}, {y_val})")

The attribute names on the left of = are the actual attribute names of the class, and the right side is the capture pattern that binds the value. You can also use positional patterns if the class defines __match_args__.

Wildcard and Ignoring Values

The wildcard pattern _ is a special case: it matches any value but does not bind it. This is useful when you need to match a structure but ignore certain elements. For example:

match record: case (name, _, age): print(f"{name} is {age} years old")

The underscore is not a capture pattern; it does not create a variable. You cannot use _ as a regular variable name in that context because it is reserved for wildcard behavior. If you need to bind a value but want to indicate that it is intentionally unused, you can use a name like _unused, but that will bind the value.

Common Mistakes and Pitfalls

One common mistake is using the same capture name multiple times in a single pattern. Python does not allow repeated capture names; each name must be unique within a pattern. For example, case (x, x): raises a SyntaxError because the same variable is captured twice. This is different from some other languages where repeated names imply equality.

Another pitfall is confusing capture patterns with literal values. A bare name always captures; it never compares against an existing variable. If you want to match against a variable's value, you need to use a value pattern with a dotted name or a guard. For example:

expected = 5 match value: case expected: # This captures, not compares! ...

To compare, use a guard:

case _ if value == expected:

Performance and Runtime Considerations

Capture patterns themselves have negligible runtime cost; they are just variable assignments after a successful match. The main performance consideration is the order of case clauses. Python evaluates cases in order and stops at the first match. Placing more specific patterns before general capture patterns avoids unnecessary work and ensures correct behavior. For example, put case (0, y) before case (x, y).

When to Use Capture Patterns vs. Regular Assignment

Capture patterns are most valuable when you need to destructure data based on its shape or type. They replace verbose isinstance checks and manual attribute access. However, for simple variable assignment, a regular assignment is clearer. Use capture patterns when you are already using match to dispatch on structure.

python capture pattern: Practical Usage and Code Examples | RYUSLOG DEV