Обработка остальных вариантов с помощью wildcard case

Раздел: Основы Python -> Условные операторы

Сопоставление с образцом в Python: общий случай

Оператор match (появился в Python 3.10) позволяет сопоставлять значение с набором шаблонов. Для обработки всех значений, не соответствующих ни одному из заданных шаблонов, используется символ подчёркивания _ (wildcard). Это аналог ветки else в других языках, но синтаксически записывается как case _:.

Основное решение: использование case _

В блоке match последний вариант с case _: срабатывает, если ни один предыдущий шаблон не подошёл. Такой подход делает код коротким и читаемым.

Пример: проверка статуса HTTP-ответа.

status = 404

match status:
    case 200:
        message = "OK"
    case 301 | 302:
        message = "Redirect"
    case 400:
        message = "Bad Request"
    case _:
        message = "Unknown status"

print(message)  # Unknown status

значение else python (значение else в python)

Здесь case _ перехватывает все значения, не совпавшие с перечисленными. Если в коде не предусмотреть такой ветки, при отсутствии совпадения возникнет ошибка (нет MatchError, но тело match не выполнится, а переменная может остаться неопределённой).

Типичная ошибка:

Попытка записать case else: вместо case _:. В Python нет ключевого слова else внутри match. Использование case else: вызовет синтаксическую ошибку.

Ещё одна проблема: если внутри case _ присвоить значение переменной, она будет перекрывать внешнюю область видимости. Лучше использовать _ только как wildcard, а не как имя переменной.

Как реализовать множественный выбор без match-case?

До версии 3.10 и в случаях, когда match недоступен, применяют классическую цепочку if-elif-else. Этот способ понятен и работает в любом Python.

status = 404

if status == 200:
    message = "OK"
else:
    message = "Unknown status"

print(message)  # Unknown status

Python case else (конструкция case else в python)

Недостатки: для разветвлённых условий код становится громоздким, особенно при сопоставлении составных структур (кортежей, словарей). Также сложнее реализовать OR-шаблоны (приходится дублировать условия).

Проблема:

При большом количестве вариантов увеличивается глубина вложенности и вероятность ошибок. Для сопоставления с распаковкой (например, координаты точки) требуется ручное извлечение элементов.

Как альтернативно организовать выбор на основе значения с помощью словаря?

Если ветки соответствуют простым значениям (строкам, числам), можно использовать словарь как диспетчер. Это часто короче, чем if-elif.

status = 404

messages = {
    200: "OK",
    301: "Redirect",
    302: "Redirect",
    400: "Bad Request"
}

message = messages.get(status, "Unknown status")
print(message)  # Unknown status

какие логические операторы используются в python (какие логические операторы используются в python)

Словарь позволяет быстро получить результат по ключу, но не поддерживает сложные шаблоны (распаковку, OR нескольких значений в одном ключе). Также требуется отдельно обрабатывать отсутствующие ключи.

Проблема:

Не все ветки можно выразить простым ключом. Например, невозможно объединить 301 и 302 в один ключ без дополнительной логики. Приходится дублировать значения или использовать отдельный вызов функции.

Как наложить дополнительные условия на catch-all в match-case?

Символ подчёркивания можно комбинировать с guard (условие после if). Это позволяет обработать все оставшиеся значения только при выполнении дополнительной проверки.

value = 15

match value:
    case x if x > 10:
        print(f"Больше 10: {x}")
    case _ if value < 0:
        print("Отрицательное число")
    case _:
        print("Другое значение")

Здесь после case _ if value < 0 выполняется только для отрицательных чисел, а последний case _ перехватывает всё остальное.

Проблема:

Порядок case важен: более общие шаблоны должны располагаться после более конкретных. Если поставить case _ с guard раньше, чем конкретные шаблоны, guard может сработать и перекрыть более точные совпадения.

- Python число больше и меньше (сравнение чисел (больше/меньше) в python)
- Python if несколько условий (проверка нескольких условий с помощью if в python)
- конструкция if elif else в python (конструкция if-elif-else в python)

Расширенные примеры использования match-case

Далее приведены редкие и неочевидные сценарии, демонстрирующие гибкость match с wildcard и guard.

Сопоставление с кортежами и вложенный wildcard

Можно сопоставлять кортежи произвольной длины, используя _ для отдельных элементов.

Пример
point = (3, 0, 5)

match point:
    case (x, 0, z):
        print(f"Точка на оси X-Z: ({x}, 0, {z})")
    case (_, y, _) if y < 0:
        print(f"Точка с отрицательной Y: {point}")
    case _:
        print("Прочая точка")
Точка на оси X-Z: (3, 0, 5)

Динамическое создание шаблонов с помощью OR

Оператор | позволяет объединить несколько шаблонов в одном case.

Пример
command = "quit"

match command:
    case "quit" | "exit" | "bye":
        print("Завершение программы")
    case "help" | "?":
        print("Справка")
    case _:
        print("Неизвестная команда")
Завершение программы

Захват части структуры с помощью as

Ключевое слово as позволяет сохранить сопоставленную часть в переменную.

Пример
data = {"name": "Alice", "age": 30}

match data:
    case {"name": str(name), "age": int(age)}:
        print(f"Пользователь {name}, возраст {age}")
    case {"name": name} as other if "age" not in other:
        print(f"Только имя: {name}")
    case _:
        print("Неизвестный формат")
Пользователь Alice, возраст 30

Использование wildcard в списках с переменной длиной

Для списков *_ означает произвольное количество элементов.

Пример
values = [1, 2, 3, 4]

match values:
    case [first, *_]:
        print(f"Первый элемент: {first}")
    case _:
        print("Пустой список")
Первый элемент: 1

Обработка исключений с помощью match

Хотя это нестандартно, можно комбинировать match с try-except для анализа исключения.

Пример
try:
    1 / 0
except ZeroDivisionError as err:
    match err:
        case ZeroDivisionError() if "division by zero" in str(err):
            print("Деление на ноль перехвачено")
        case _:
            print("Другая ошибка деления")
Деление на ноль перехвачено

Примечание:

Во всех примерах case _ гарантирует, что даже если ни один из предыдущих шаблонов не совпадёт, выполнение не упадёт с ошибкой. Это особенно важно при обработке пользовательского ввода.

конструкция case else в Python - comments

En
Python case else (python)