<MyRusakov.ru />

Профессиональная Web-разработка. Дизайн, код и автоматизация

Профессиональная Web-разработка. Дизайн, код и автоматизация

Это очень подробный курс из разряда "всё включено". Разбираются следующие темы: HTML, CSS, SCSS, JavaScript, PHP, SQL, Laravel, Nginx, PostCSS, npm, Vite, Vitest, Composer, PHPUnit, Prettier, Stylelint, ESLint, Pint, Larastan, Git, Agile, Scrum, Docker, Supervisord, Figma, Stitch AI, Confluence, Jira.

Рассчитан и на новичков, и на тех, кто уже знаком с основами, но хочет освоить полный цикл разработки.

Помимо самой теории, Вы увидите пример создания Web-проекта на 20 000 строк кода: от идеи и документации на Confluence через планирование на Jira, fullstack-разработку до деплоя на VPS.

Помимо уроков, курс содержит упражнения для закрепления знаний и финальное тестирование. А ещё Вы получите 5 полноценных Бонусных курсов: «GitLab под ключ», «Вёрстка сайта с нуля 2.0», «JavaScript с Нуля до Гуру 2.0», «PHP и MySQL с Нуля до Гуру 3.0» и «Laravel от А до Я».

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

match/case в Python: структурное сопоставление с образцом простыми словами и примерами

match/case в Python: структурное сопоставление с образцом простыми словами и примерами

Структурное сопоставление с образцом (pattern matching) — это одна из самых заметных возможностей Python 3.10+. Новый оператор match/case делает разбор сложных данных выразительным и безопасным: вы описываете форму данных (образец), а Python проверяет, подходят ли реальные значения под заданный шаблон.

Что такое match/case в Python

Оператор match сравнивает значение с одним или несколькими образцами в блоках case. В отличие от классического цепочки if/elif, вы сопоставляете структуру данных: литералы, последовательности, словари, а также экземпляры классов.

def classify(x):
    match x:
        case 0:
            return "ноль"
        case 1 | 2 | 3:
            return "малое число"
        case _:
            return "что-то ещё"

print(classify(2))   # малое число
print(classify(10))  # что-то ещё

Базовый синтаксис match/case

  • Литералы: case 0, case "ok"
  • Альтернативы: case 1 | 2 | 3
  • Подстановочный символ: case _ (любой другой вариант)
  • Гарды (условия): case pattern if условие:
def describe(n):
    match n:
        case int() if n < 0:
            return "отрицательное целое"
        case int() if n % 2 == 0:
            return "чётное целое"
        case int():
            return "нечётное целое"
        case float():
            return "вещественное"
        case _:
            return "не число"

Сопоставление последовательностей (списки, кортежи)

Можно матчить форму списка или кортежа, извлекая элементы и «хвост». Последовательности должны целиком соответствовать образцу.

def handle_event(event):
    match event:
        case ["PING"]:
            return "pong"
        case ["ADD", x, y]:
            return x + y
        case ["AVG", x, y, *rest]:  # rest — оставшиеся значения
            nums = [x, y, *rest]
            return sum(nums) / len(nums)
        case [cmd, *args]:
            return f"неизвестная команда {cmd} с аргументами {args}"
        case _:
            return "неверный формат"

print(handle_event(["ADD", 2, 3]))     # 5
print(handle_event(["AVG", 2, 4, 6]))  # 4.0

Важно: строковые типы по умолчанию не считаются последовательностями для pattern matching (во избежание сюрпризов), поэтому case [x, y] не «разрежет» строку на буквы.

Сопоставление словарей (mapping patterns)

Можно матчить по ключам и одновременно извлекать значения. Ключи, указанные в образце, должны присутствовать, а остальные — игнорируются (если не использовать "**rest").

def parse_response(resp):
    match resp:
        case {"status": 200, "data": data}:
            return ("ok", data)
        case {"status": 404, "message": msg}:
            return ("not_found", msg)
        case {"status": code} if 400 <= code < 500:
            return ("client_error", code)
        case {"status": code, **rest}:
            return ("other_status", code, rest)
        case _:
            return ("bad_format", None)

print(parse_response({"status": 200, "data": [1,2,3]}))
# ('ok', [1, 2, 3])

Классовые паттерны (class patterns) без dataclasses

Сопоставление может работать с вашими классами. Чтобы матчить позиционно (а не только по именованным аргументам), определите __match_args__ — кортеж имён атрибутов по порядку.

class Point:
    __match_args__ = ("x", "y")  # порядок для позиционного сопоставления

    def __init__(self, x, y):
        self.x = x
        self.y = y

def locate(p):
    match p:
        case Point(0, 0):
            return "origin"
        case Point(x, y) if x == y:
            return f"on diagonal at {x}"
        case Point(x, y):
            return f"point at ({x}, {y})"
        case _:
            return "not a point"

print(locate(Point(0,0)))     # origin
print(locate(Point(2,2)))     # on diagonal at 2
print(locate(Point(3,5)))     # point at (3, 5)

Альтернативы, подстановки и «as»-связывание

  • | — перечисление допустимых вариантов
  • _ — любое значение (не сохраняется)
  • as — сохранить успешно совпавшее значение
def parse_packet(pkt):
    match pkt:
        case ("ERR", int() as code, msg):
            return {"ok": False, "code": code, "msg": msg}
        case ("OK", data) | ("SUCCESS", data):
            return {"ok": True, "data": data}
        case _ as unknown:
            return {"ok": False, "unknown": unknown}

print(parse_packet(("OK", {"id": 1})))
# {'ok': True, 'data': {'id': 1}}

Практический пример: простой разбор CLI-команд

Давайте разберём match case python примеры на задаче обработки аргументов командной строки. Так код получается короче и безопаснее, чем с длинными if/elif.

import sys

def cli(argv):
    match argv:
        case ["init"]:
            return "инициализация репозитория"
        case ["add", *files] if files:
            return f"добавлены файлы: {', '.join(files)}"
        case ["commit", "-m", msg]:
            return f"коммит с сообщением: {msg}"
        case ["push", remote, branch]:
            return f"отправка в {remote} {branch}"
        case ["help"] | []:
            return "usage: init | add FILE... | commit -m MSG | push REMOTE BRANCH"
        case _:
            return "неизвестная команда; используйте 'help'"

if __name__ == "__main__":
    print(cli(sys.argv[1:]))

Типичные ошибки и как их избежать

  • Ожидание «провала» (fallthrough) как в switch. В Python каждый case самодостаточен — провала нет. Ставьте несколько альтернатив через | или дублируйте логику явно.
  • Сравнение с переменной-константой. В паттерне одиночное имя — всегда захват переменной, а не сравнение. Чтобы свериться с константой, используйте точечное имя:
    case constants.OK: или литерал case 200:.
  • Неверная форма данных. Для последовательностей длина и структура должны совпадать с образцом, иначе переход к следующему case.
  • Слишком общие паттерны выше частных. Сначала размещайте более узкие case, затем общие (_).

Производительность и удобство

match/case часто короче и читабельнее длинных if/elif. По скорости — сравнимо, а иногда быстрее, когда сопоставляется структура без дополнительных проверок. Главное — использовать его по назначению: для разбора формата данных и распаковки значений.

Где полезен match/case

  • Парсинг ответов API и протоколов
  • Разбор DSL-команд и конфигураций
  • Фильтрация и классификация событий
  • Импорт/валидация данных с чёткой структурой

Версии Python и совместимость

Оператор доступен с Python 3.10+. Если вы поддерживаете более старые версии, оставьте альтернативную реализацию на if/elif, а использование match/case — за фиче-флагом или в отдельных модулях.

Небольшой чек‑лист лучших практик

  • Начинайте с частных паттернов, затем — общие и, в конце, _.
  • Используйте гарды (if) для доп. условий вместо вложенных if внутри case.
  • Храните константы в модулях/Enum и матчьте дот‑имена (value patterns).
  • Для классов определяйте __match_args__ или используйте именованные поля в паттерне.
  • Покрывайте кейсы тестами — ветвление может быть обширным.

Дополнительные примеры для закрепления

# 1) Разбор HTTP-подобного сообщения
msg = {"method": "POST", "path": "/users", "json": {"name": "Ann"}}
match msg:
    case {"method": "GET", "path": path}:
        print("read", path)
    case {"method": "POST", "path": "/users", "json": {"name": name}}:
        print("create user", name)
    case {"method": m, **rest}:
        print("method", m, "other", rest)

# 2) Совмещение вариантов и гарда
record = ("USER", {"id": 10, "role": "admin"})
match record:
    case ("USER" | "ACCOUNT", {"role": role}) if role == "admin":
        print("admin access")
    case _:
        print("regular")

# 3) Захват всего совпавшего через 'as'
value = ("ERR", 500, "server error")
match value:
    case ("ERR", int() as code, msg) as whole:
        print("ошибка", code, "подробно:", whole)

Хотите быстро закрепить знания на практике?

Если вы хотите системно прокачать Python, закрыть пробелы в основах и уверенно писать код с современными фичами вроде match/case, рекомендую курс: Пройти программу «Программирование на Python с Нуля до Гуру» и начать практиковаться уже сегодня.

Итоги

Оператор match/case — мощный инструмент для выразительного и безопасного разбора структур данных в Python 3.10+. Он упрощает код, делает ветвления наглядными и помогает избежать ошибок, характерных для многоуровневых if/elif. Освойте базовые паттерны (литералы, последовательности, словари, классы), используйте гарды и аккуратно управляйте порядком case — и ваш код станет короче, чище и понятнее. Запрос «match case python примеры» закрывается этой статьёй: теперь вы знаете, как применять сопоставление с образцом в ежедневной практике.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.