3.10. OOP Pattern Matching¶
3.10.1. Problem¶
>>> language = 'English'
>>>
>>> if language == 'Polish':
... result = 'Cześć'
... elif language == 'English':
... result = 'Hello'
... elif language == 'German':
... result = 'Guten Tag'
... elif language == 'Spanish':
... result = 'Buenos Días'
... elif language == 'Chinese':
... result = '你好'
... elif language == 'French':
... result = 'Bonjour'
... else:
... result = 'Unknown language'
>>>
>>> print(result)
Hello
3.10.2. Switch¶
In other languages you may find switch
statement:
(note that this is not a valid Python code)
>>> language = 'English'
>>>
>>> switch(language):
... case 'Polish': result = 'Cześć'
... case 'English': result = 'Hello'
... case 'German': result = 'Guten Tag'
... case 'Spanish': result = 'Buenos Días'
... case 'Chinese': result = '你好'
... case 'French': result = 'Bonjour'
... default: result = 'Unknown language'
>>>
>>> print(result)
Hello
3.10.3. Pattern Matching¶
Since Python 3.10: PEP 636 -- Structural Pattern Matching: Tutorial
>>> language = 'English'
>>>
>>> match language:
... case 'Polish': result = 'Cześć'
... case 'English': result = 'Hello'
... case 'German': result = 'Guten Tag'
... case 'Spanish': result = 'Buenos Días'
... case 'Chinese': result = '你好'
... case 'French': result = 'Bonjour'
... case _: result = 'Unknown language'
>>>
>>> print(result)
Hello
3.10.4. Behavior¶
Statement |
Meaning |
---|---|
|
assign x = subject |
|
test subject == 'x' |
|
test subject == x.y |
|
test isinstance(subject, x) |
|
test isinstance(subject, Mapping) and subject.get('x') == 'y' |
|
test isinstance(subject, Sequence) and len(subject) == 1 and subject[0] == 'x' |
3.10.5. Matching Alternatives¶
>>> status = 418
>>>
>>>
>>> match status:
... case 400:
... result = 'Bad request'
... case 401 | 403 | 405:
... result = 'Not allowed'
... case 404:
... result = 'Not found'
... case 418:
... result = "I'm a teapot"
... case _:
... result = 'Unexpected status'
3.10.6. Matching on Sequence¶
>>> request = 'GET /index.html HTTP/2.0'
>>>
>>>
>>> match request.split():
... case ['GET', uri, version]:
... server.get(uri)
... case ['POST', uri, version]:
... server.post(uri)
... case ['PUT', uri, version]:
... server.put(uri)
... case ['DELETE', uri, version]:
... server.delete(uri)
3.10.7. Matching on Sequence with Assignment¶
>>> class Hero:
... def action(self):
... return ['move', 'left', 20]
>>>
>>>
>>> match hero.action():
... case ['move', ('up'|'down'|'left'|'right') as direction, value]:
... hero.move(direction, value)
... case ['make_damage', value]:
... hero.make_damage(value)
... case ['take_damage', value]:
... hero.take_damage(value)
3.10.8. Matching on Enum¶
>>> from enum import Enum
>>>
>>>
>>> class Key(Enum):
... ESC = 27
... ARROW_LEFT = 37
... ARROW_UP = 38
... ARROW_RIGHT = 39
... ARROW_DOWN = 40
>>>
>>>
>>> match keyboard.on_key_press():
... case Key.ESC:
... game.quit()
... case Key.ARROW_LEFT:
... hero.move_left()
... case Key.ARROW_UP:
... hero.move_up()
... case Key.ARROW_RIGHT:
... hero.move_right()
... case Key.ARROW_DOWN:
... hero.move_down()
... case _:
... raise ValueError(f'Unrecognized key')
3.10.9. References¶
- 1
Raymond Hettinger. Retrieved: 2021-03-07. URL: https://twitter.com/raymondh/status/1361780586570948609?s=20