DS
Size: a a a
DS
DA
DS
DA
DI
DI
M
M
M
DI
if
statement on steroids.match
as switch statement:def http_error(status: int) -> str:
match status:
case 400:
return 'Bad request'
case 401:
return 'Unauthorized'
case _:
return 'Something else'
def inspect(obj) -> None:
match obj:
case 0 | 1 | 2: # matching 2 or more exact values
print('small number')
case x if x > 2: # guards
print('big positive number')
case [] | [_]: # matching sequence
print('zero or one element sequence')
case [x, _, *_]: # unpacking to match rest
print('2 or more elements sequence')
print(f'the first element is {x}')
case {'route': route}: # matching dicts
print(f'dict with ONLY `route` key which is {route}')
case {'route': _, **_}: # matching rest for dicts
print(f'dict with `route` key')
case str() | bytes(): # matching types
print('something string-like')
case [x := [_, *_]]: # walrus and sub-patterns
print('non-empty list inside a list')
case _: # default case
print('something else')
__match__
magic method. For object
it does isinstance
check. This is why case str()
works:class object:
@classmethod
def __match__(cls, obj):
if isinstance(obj, cls):
return obj
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
match obj:
case Point(x=0, y=0):
print('both x and y are zero')
case Point():
print('it is a point')
case _:
print('something else')
__match_args__
, the given arguments can be positional in the pattern:class Point:
__match_args__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
match obj:
case Point(0, 0): # here args are positional now
print('both x and y are zero')
DS
DS
DS
KT
МС
A
A