Больше новшеств Python 3.10.
От версии к версии Python дарит нам разные новые возможности сделать наш код более понятным, более подходящим под задачи. На этот раз появится оператор match-case. В некотором смысле он похож на паттерн-матчинг оператор из функциональных языков.
В общем случае его можно описать как расширенный switch-case, однако, куда более крутой:
match command.split():
case ["quit"]: ... # Code omitted for brevity
case ["go", direction]: ...
case ["drop", *objects]: ...
... # Other cases
case _:
print(f"Sorry, I couldn't understand {command!r}")
В match
мы указываем значение для сопоставления, в case
- значения,
которые могут подходить. При чём, это могут быть композитные значения.
В предложенном примере после метода split
значением будет массив -
введённая команда, разделённая на части по пробелу. Тогда благодаря
match-case
мы можем обработать разные ситуации: когда одно слово "quit",
когда несколько слов а ля "go" и какое-то "направление" и т.д.
Иными словами, от входящего значения мы можем описать разные сценарии. При предыдущих "if-else" это было бы не так просто, не так очевидно.
Более того! Мы можем использовать сопоставление с образцом - объектом.
То есть (если вы такой ленивец-негодяй-панк, что не следите за типами в апи)
можно обрабатывать входящие данные без isinstance
:
match event.get():
case Click(position=(x, y)):
handle_click_at(x, y)
case KeyPress(key_name="Q") | Quit():
game.quit()
case KeyPress(key_name="up arrow"):
game.go_north()
...
case KeyPress():
pass # Ignore other keystrokes
case other_event:
raise ValueError(f"Unrecognized event: {other_event}")
Разные типы - разные обработчики! Равно как и разные значения типов...
Можно также использовать позиционные атрибуты (это по мне - вообще рвань!):
from dataclasses import dataclass
@dataclass
class Click:
position: tuple
button: Button
match event.get():
case Click((x, y)):
handle_click_at(x, y)
Или без dataclass
через магический аттрибут __match_args__ = ["position", "button"]
-
ещё одна фигня, на которой будут отыгрываться "злые" рекрутеры.
Вам мало? Вот ещё это работает с "or":
case 401 | 403 | 404:
return "Not allowed"
или диктами:
case {"text": str(message), "color": str(c)}:
ui.set_text_color(c)
ui.display(message)
"Ахаха, Девид Блейн, прекрати!" - держите ещё guard-условия:
case Point(x, y) if x == y:
print(f"Y=X at {x}")
В общем, завезли много нового, пусть и в одном операторе.