Структурное сопоставление (match-case) в Python 3.10+
🔍 Введение: Что такое match-case?
Представьте, что перед вами огромный сундук с разными отделениями. В зависимости от того, что вы в него положите (книгу, яблоко или ключ), открывается определенный отсек. Вот так и match-case в Python — это мощный и элегантный способ обрабатывать разные варианты данных без горы if-elif-else!
До Python 3.10 мы писали так:
status = 404
if status == 200:
print("Успех!")
elif status == 404:
print("Не найдено")
else:
print("Ошибка")
А теперь можно так:
status = 404
match status:
case 200:
print("Успех!")
case 404:
print("Не найдено")
case _:
print("Ошибка")
Чище, понятнее, и сразу видно все варианты!
🧩 Основы синтаксиса: Как это работает?
Синтаксис match-case состоит из:
- match — указываем переменную для анализа
- case — шаблоны для сравнения
- _ — wildcard (как else)
Простые сравнения
def greet(name):
match name:
case "Данила":
return "Привет, преподаватель! 👨🏫"
case "Анна":
return "Привет, Аня! 👋"
case _:
return f"Привет, {name}!"
Сравнение с кортежами
coords = (0, 1)
match coords:
case (0, 0):
print("Точка начала координат")
case (x, 0):
print(f"На оси X: {x}")
case (0, y):
print(f"На оси Y: {y}")
case (x, y):
print(f"Где-то в пространстве: {x}, {y}")
🔥 Продвинутые возможности
Распаковка значений
users = [
("Алексей", "admin"),
("Мария", "user"),
]
for user in users:
match user:
case (name, "admin"):
print(f"{name} — администратор")
case (name, "user"):
print(f"{name} — обычный пользователь")
Сочетание с условиями (guards)
def check_age(age):
match age:
case x if x < 0:
return "Возраст не может быть отрицательным!"
case 18:
return "Только что совершеннолетие!"
case _ if age > 100:
return "Вам нужно отдохнуть!"
case _:
return f"Ваш возраст: {age}"
🏆 Реальные кейсы применения
Обработка HTTP-запросов (упрощённый пример)
def handle_request(request):
match request:
case {"method": "GET", "path": "/users"}:
return get_users()
case {"method": "POST", "path": "/users", "body": body}:
return create_user(body)
case {"method": "DELETE", "path": f"/users/{id}"}:
return delete_user(id)
case _:
return {"error": "Неизвестный запрос"}
Разбор AST (Abstract Syntax Tree)
def evaluate(expr):
match expr:
case ["+", left, right]:
return evaluate(left) + evaluate(right)
case ["-", left, right]:
return evaluate(left) - evaluate(right)
case ["*", left, right]:
return evaluate(left) * evaluate(right)
case [op, *_]:
raise ValueError(f"Неизвестный оператор: {op}")
💡 Производительность и подводные камни
- Не заменяет все if-else — для простых проверок
ifможет быть читаемее. - Порядок имеет значение — интерпретатор проверяет
caseсверху вниз. - Используйте
_— всегда добавляйте wildcard-case, чтобы обрабатывать неожиданные значения.
Для глубокого погружения в тему рекомендую видео Данилы Бежина:
👉 https://www.youtube.com/@DanilaBezhin
🚀 Практическое задание
Напишите функцию describe_animal, которая:
- Принимает кортеж
(тип, возраст, кличка) - Использует
match-caseдля обработки:- Собаки старше 10 лет
- Кошки с кличкой "Мурка"
- Любых других животных
Пример решения:
def describe_animal(animal):
match animal:
case ("собака", age, name) if age > 10:
return f"Пожилой пёс {name}"
case ("кошка", _, "Мурка"):
return "Это же легендарная Мурка!"
case (type_, _, name):
return f"{type_} по имени {name}"
Попробуйте расширить пример — добавьте обработку попугаев! 🦜