I have code that checks for named tuples and dataclasses by looking for a _fields
attribute:
if hasattr(candidate, '_fields'):
do_action()
How can I express this with Python 3.10's match/case structural pattern matching?
PEP 634 for structural pattern matching documents this capability as a class pattern:
cls()
will do an isinstance() test.cls(attr=variable)
tests for the presence of an attribute and binds the value to the variable.To emulate a hasattr() for duck typing:
_fields
, the attribute that must be present._
if you don't need to capture the value or to some other variable name if you do want to capture the value.Your specific example, if hasattr(candidate, '_fields'): do_action()
, translates to:
match candidate:
case object(_fields=_):
do_action()
This shows how all the parts fit together:
from typing import NamedTuple
from dataclasses import dataclass
class Whale(NamedTuple):
name: str
num_fins: int
@dataclass
class Vehicle:
name: str
num_wheels: int
subject = Vehicle('bicycle', 2)
match subject:
case object(num_fins=n):
print(f'Found {n} fins')
case object(num_wheels=_):
print(f'Found wheeled object')
case _:
print('Unknown')
This script outputs:
Found wheeled object