Введение
Конструкция match-case появилась в версии Python 3.10. С её помощью можно сопоставлять значение с так называемым образцом (pattern matching).
В данной статье разберём, как работает конструкция match-case в Python, и рассмотрим примеры использования.
Конструкция match-case
Конструкция match-case начинается с ключевого слова match, за которым следует выражение, значение которого будет сравниваться с образцами в каждом из блоков case.
Синтаксис выглядит следующим образом:
match выражение:
case образец_1:
# действия, если совпадение с образцом_1
case образец_2:
# действия, если совпадение с образцом_2
case _:
# действия, если ни один из образцов не совпал (опционально)
- Выражение — это переменная или результат вычисления, который проверяется на соответствие образцам.
- Образец — описание структуры или значения, с которым сравнивается выражение.
- _ (подчеркивание) — универсальный шаблон, соответствующий любому значению. Используется в качестве блока «по умолчанию».
Пример использования конструкции match-case
command = "start"
match command:
case "start":
print("Запуск программы")
case "stop":
print("Остановка программы")
case _:
print("Неизвестная команда")
# Вывод: Запуск программы
Как работает сопоставление с образцом
- Python проверяет значение выражения из match с каждым образцом в блоках case последовательно.
- Если находится соответствие, выполняется код в теле этого блока.
- Если ни один из образцов не подходит, выполняется блок case _, если он указан.
- Внутри блока case можно использовать переменные, подстановки и дополнительные проверки.
Типы образцов
Образцы — это структуры или значения, которые используются для проверки соответствия выражению в конструкции match. Они позволяют описывать данные в различных формах, от простых литералов до сложных вложенных структур.
Литералы
Литералы — это конкретные значения, такие как числа, строки, или None. Если значение выражения совпадает с литералом, соответствующий блок case выполняется.
x = 1
match x:
case 1:
print("Один")
case "hello":
print("Привет")
# Вывод: Один
По итогу значение x проверяется на равенство числу 1 или строке «hello».
Классы и объекты
Мы можем сравнивать значение с экземплярами классов и одновременно распаковывать их атрибуты.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
point = Point(1, 2)
match point:
case Point(x=1, y=2):
print("Точка находится в (1, 2)")
case Point(x=_, y=_):
print("Какая-то другая точка")
# Вывод: Точка находится в (1, 2)
В данном случае Point(x=1, y=2) проверяет, совпадают ли значения атрибутов x и y с указанными.
Последовательности
Ещё, с помощью конструкции match-case можно проверять значения последовательностей, таких как списки, кортежи или строки. Для этого используются квадратные скобки, а подчеркивание (_) обозначает произвольные элементы.
data = [1, 2, 3]
match data:
case [1, 2, 3]:
print("Полное совпадение списка")
case [1, *_]:
print("Список начинается с единицы")
# Вывод: Полное совпадение списка
Тут [1, *_] обозначает список, который начинается с 1, а остальные элементы игнорируются.
Шаблоны с подстановкой переменных
Сопоставление позволяет извлекать данные из структуры и сохранять их в переменные.
x = (1, 2)
match x:
case (a, b):
print(f"Два значения: {a} и {b}")
В данном примере a и b будут содержать элементы кортежа x.
Объединение с оператором |
Оператор | позволяет указать несколько альтернативных образцов в одном блоке case. Это аналог оператора or для условий.
x = 2
match x:
case 1 | 2 | 3:
print("Это 1, 2 или 3")
# Вывод: Это 1, 2 или 3
Блок выполнится, если x равен 1, 2 или 3.
Шаблоны с условиями
Ещё мы можем добавить дополнительное условие к образцу с помощью конструкции if. Это позволяет уточнять, когда именно должен сработать блок case.
x = (5, 3)
match x:
case (a, b) if a > b:
print(f"Первое число больше: {a} > {b}")
# Вывод: Первое число больше: 5 > 3
Блок выполняется только если первое число в кортеже больше второго.
Реальные примеры использования
Обработка пользовательских данных
Данный пример иллюстрирует, как можно удобно обрабатывать действия пользователя на основе кортежей с параметрами:
user_input = ("login", "admin")
match user_input:
case ("login", username):
print(f"Вход пользователя: {username}")
case ("logout", username):
print(f"Выход пользователя: {username}")
case ("register", username, password):
print(f"Регистрация пользователя {username} с паролем {password}")
case _:
print("Неизвестное действие")
# Вывод: Вход пользователя: admin
Разбор JSON-подобных структур
При работе с ответами от API или сложными словарями, можно использовать match-case:
response = {"status": "ok", "data": [1, 2, 3]}
match response:
case {"status": "ok", "data": list(data)} if data:
print(f"Получены данные: {data}")
case {"status": "error", "message": msg}:
print(f"Ошибка: {msg}")
case {"status": "ok"}:
print("Данные отсутствуют")
case _:
print("Неизвестный формат ответа")
# Вывод: Получены данные: [1, 2, 3]
Разбор вложенных структур
Сопоставление с образцом отлично справляется с вложенными структурами, например, при обработке данных в виде дерева:
node = {"type": "binary", "left": {"value": 1}, "right": {"value": 2}}
match node:
case {"type": "binary", "left": {"value": left}, "right": {"value": right}}:
print(f"Бинарный узел с левым значением {left} и правым {right}")
case {"type": "leaf", "value": value}:
print(f"Лист с значением {value}")
case _:
print("Неизвестный узел")
# Вывод: Бинарный узел с левым значением 1 и правым 2
Обработка ошибок с различными уровнями детализации
Использование match-case упрощает обработку исключений/ошибок с различными типами данных:
error = {"code": 404, "message": "Not Found"}
match error:
case {"code": 404, "message": msg}:
print(f"Ошибка 404: {msg}")
case {"code": 500}:
print("Ошибка 500: Внутренняя ошибка сервера")
case _:
print("Неизвестная ошибка")
# Вывод: Ошибка 404: Not Found
Заключение
В ходе статьи мы с Вами узнали про то, как работает конструкция match-case в Python и рассмотрели несколько примеров. Надеюсь Вам понравилась статья, желаю удачи и успехов! 🙂
Мой Telegram канал
Мой YouTube канал
Курс по созданию телеграм-ботов на Python с фреймворком Aiogram