match / case: сопоставление шаблонов
match / case: сопоставление шаблонов
Вы уже умеете выбирать между несколькими вариантами с помощью if/elif/else. Когда вариантов становится много, цепочки elif с проверкой равенства начинают выглядеть однообразно и громоздко. В Python 3.10 появился оператор match/case — мощный инструмент сопоставления с образцом (pattern matching).
Базовый синтаксис
match переменная:
case значение1:
# если переменная == значение1
case значение2:
# если переменная == значение2
case _:
# случай по умолчанию (аналог else)
Простой пример — команды CLI:
command = input("Команда (start/stop/status): ")
match command:
case "start":
print("Запускаем сервер...")
case "stop":
print("Останавливаем сервер...")
case "status":
print("Статус: работает")
case _:
print(f"Неизвестная команда: {command}")
Это то же самое, что длинный if/elif/else, но намного читабельнее. _ в case _: — специальный символ «совпасть со всем остальным».
Сравнение с if/elif
Без match:
day = "понедельник"
if day == "понедельник":
print("Начало недели")
elif day == "пятница":
print("Конец рабочей недели")
elif day == "суббота" or day == "воскресенье":
print("Выходной")
else:
print("Середина недели")
С match:
day = "понедельник"
match day:
case "понедельник":
print("Начало недели")
case "пятница":
print("Конец рабочей недели")
case "суббота" | "воскресенье":
print("Выходной")
case _:
print("Середина недели")
Обратите внимание на "суббота" | "воскресенье" — оператор | внутри case означает «или», позволяя объединить несколько шаблонов.
Сопоставление с несколькими значениями через |
status_code = 404
match status_code:
case 200 | 201 | 204:
print("Успех")
case 301 | 302:
print("Перенаправление")
case 400:
print("Неверный запрос")
case 401 | 403:
print("Ошибка авторизации")
case 404:
print("Не найдено")
case 500 | 502 | 503:
print("Ошибка сервера")
case _:
print("Неизвестный статус")
Сопоставление кортежей и последовательностей
match/case умеет сопоставлять структуры данных, а не только скалярные значения. Например, пары значений:
point = (0, 5)
match point:
case (0, 0):
print("Начало координат")
case (x, 0):
print(f"На оси X: x = {x}")
case (0, y):
print(f"На оси Y: y = {y}")
case (x, y):
print(f"Точка ({x}, {y})")
Здесь происходит нечто интересное: case (x, 0) — это не просто сравнение с (x, 0). Это шаблон с захватом: если второй элемент равен 0, а первый — любой, то первый элемент захватывается в переменную x. Для point = (0, 5) → первый case ложный (не (0, 0)), второй ложный (второй элемент 5, не 0), третий истинный → y = 5.
Охранные условия (guard)
К любому case можно добавить дополнительное условие через if:
age = 25
match age:
case n if n < 0:
print("Некорректный возраст")
case n if n < 18:
print(f"Несовершеннолетний: {n} лет")
case n if n < 65:
print(f"Взрослый: {n} лет")
case n:
print(f"Пенсионный возраст: {n} лет")
Здесь n захватывает значение переменной age, а if n < 0 — охранное условие. Это гибрид match и if в одном синтаксисе.
Когда использовать match, а когда if/elif
match/case предпочтителен, когда:
- Нужно выбрать действие из нескольких по значению одной переменной.
- Несколько
caseможно объединить через|. - Работаете со структурированными данными (кортежи, словари, объекты).
if/elif/else предпочтителен, когда:
- Условия разнородные (сравниваются разные переменные).
- Логика сложнее простого «это значение или то».
- Нужна совместимость с Python < 3.10.
Версионное ограничение
match/case доступен начиная с Python 3.10. Если у вас более старая версия — конструкция вызовет SyntaxError. Проверьте версию через python3 --version. Для учебных целей мы предполагаем Python 3.10+.
Проверь себя
Что выведет этот код?
code = "B"
match code:
case "A" | "B":
print("Первые буквы")
case "C":
print("Третья буква")
case _:
print("Другое")
code = "B" совпадает с шаблоном "A" | "B" → выводится "Первые буквы".
Итог
match/case(Python 3.10+) — элегантная альтернатива длинным цепочкамif/elif.case _:— случай по умолчанию, аналогelse.case "a" | "b":объединяет несколько значений в одной ветке.case (x, 0):— сопоставление структур с захватом значений в переменные.case n if n < 18:— охранное условие для дополнительной фильтрации.- Для простых условий с разными переменными
if/elifпо-прежнему предпочтительнее.
Модуль 3 завершён! Вы освоили все инструменты для ветвления: if/elif/else, вложенные условия, тернарное выражение, truthy/falsy и match/case. В следующем модуле переходим к циклам — научимся повторять действия.