Альтернатива Python оператору Switch из C/C++

Привет! Сегодня я решил поделиться относительно новым дополнением к языку программирования Python. Под относительно новым я подразумеваю, что он увидел свет где-то в октябре 2021 года в рамках выпуска Python 3.10. Его официальное название — Структурное сопоставление с образцом, которое в значительной степени говорит все, что нам нужно знать о том, что это такое и что оно делает.

Будучи очень похожим на оператор switch языка C, где он успешно заменил несколько операторов if-else if, ориентированных на значение переменной, этот новый синтаксис сопоставления структурных шаблонов, представленный в Python 3.10, а точнее оператор match, также помогает сохраняя наш код как можно более простым, успешно решая ситуацию, в которой потребуется несколько операторов if-elif, и каждый из них будет диктовать определенные инструкции на основе значения одной переменной.

Сосредоточившись на демонстрации сходства между двумя операторами, а именно оператором switch в C и более новым оператором match в Python, давайте посмотрим, как оператор switch ведет себя в C:

// declare and initialize an integer variable,
// then perform some actions based on its value
int num = 2;
switch (num) {
    case 0:
        printf("num is 0");
        break;
    case 1:
        printf("num is 1");
        break;
    case 2:
        printf("num is 2");
        break;
    default:
        printf("num has a different value");
        break;
}

Если бы мы запустили этот код, мы бы увидели, используя какой-нибудь отладчик, что он сначала объявит переменную num, затем присвоит ей значение 2, после чего будет обработан оператор switch. Обратите внимание, что оператор также имеет num в качестве параметра, поскольку именно значение этой переменной будет проверено на использование этих нескольких кодовых блоков case.

В нашем примере переменная имеет значение 2, поэтому она сначала пойдет и проверит case 0; тест провалится, так как 2 отличается от 0, тогда он пойдет и проверит case 1; этот тест также не пройден, тогда он будет проверять case 2. Этот тест будет успешным, поэтому будет выполнена инструкция по выводу num is 2. Затем оператор break выходит из оператора switch, гарантируя, что никакие другие случаи не будут проверены, и все.

Если бы наша переменная num была отличной от 0, 1 или 2, скажем, 5, наш код вернулся бы к случаю default и вывел бы num is greater than 2, так как это роль ключевого слова default в нашем примере выше.

Как нам написать тот же самый пример на Python? Во-первых, мы рассмотрим обычный, слишком знакомый, ранее доступный синтаксис Python:

# declare and initialize an integer variable,
# then perform some actions based on its value
num = 2
if num == 0:
    print("num is 0")
elif num == 1:
    print("num is 1")
elif num == 2:
    print("num is 2")
else:
    print("num has a different value")
Output:
num is 2

Это довольно значительный if-elif-else фрагмент кода, не так ли? Не так уж плохо, но и не слишком чисто. Теперь давайте изучим, как это будет выглядеть в Python, используя оператор match:

# declare and initialize an integer variable,
# then perform some actions based on its value
num = 2
match num:
    case 0:
        print("num is 0")
    case 1:
        print("num is 1")
    case 2:
        print("num is 2")
    case _:
        print("num has a different value")
Output:
num is 2

Теперь мы можем видеть, насколько чище теперь выглядит наш код. Но это еще не все, что он может сделать. Мы также можем комбинировать случаи, чтобы избежать повторения кода. Давайте рассмотрим следующий пример, где у нас есть положительное целое число, и мы должны вывести сообщение, если оно нечетное, меньше 10, и совершенно другое сообщение, если оно четное, меньше 10. Вот как бы мы это сделали без оператора match:

# declare and initialize an integer variable,
# then perform some actions based on its value
num = 4
if num == 0:
    print("num is an even, positive, less than 10 number")
elif num == 1:
    print("num is an odd, positive, less than 10 number")
elif num == 2:
    print("num is an even, positive, less than 10 number")
elif num == 3:
    print("num is an odd, positive, less than 10 number")
elif num == 4:
    print("num is an even, positive, less than 10 number")
elif num == 5:
    print("num is an odd, positive, less than 10 number")
elif num == 6:
    print("num is an even, positive, less than 10 number")
elif num == 7:
    print("num is an odd, positive, less than 10 number")
elif num == 8:
    print("num is an even, positive, less than 10 number")
elif num == 9:
    print("num is an odd, positive, less than 10 number")
else:
    print("num is not positive, or is not less than 10")
Output:
num is an odd, positive, less than 10 number

Довольно повторяющийся, не так ли? Объединим случаи с помощью оператора or:

# declare and initialize an integer variable,
# then perform some actions based on its value
num = 4
if num == 0 or num == 2 or num == 4 or num == 6 or num == 8:
    print("num is an even, positive, less than 10 number")
elif num == 1 or num == 3 or num == 5 or num == 7 or num == 9:
    print("num is an odd, positive, less than 10 number")
else:
    print("num is not positive, or is not less than 10")
Output:
num is an even, positive, less than 10 number

Немного лучше, но не так читабельно. Еще. Вместо этого воспользуемся оператором match:

# declare and initialize an integer variable,
# then perform some actions based on its value
num = 4
match num:
    case 1 | 3 | 5 | 7 | 9:
        print("num is an odd, positive, less than 10 number")
    case 0 | 2 | 4 | 6 | 8:
        print("num is an even, positive, less than 10 number")
    case _:
        print("num is not positive, or is not less than 10")
Output:
num is an even, positive, less than 10 number

Этот наивный пример демонстрирует, как мы можем комбинировать наблюдения с помощью оператора bitwise OR (|).

Мы также можем накладывать if условия на кейсы. Таким образом, мы можем дополнительно ограничить выполнение определенных случаев:

# declare and initialize an integer variable,
# then perform some actions based on its value
# also declare and initialize another variable, used to control
# which case to execute
num = 4
enable = False
match num:
    case 4 if enable is True:
        print("num is 4, enable is True")
    case 4 if enable is False:
        print("num is 4, enable is False")
Output:
num is 4, enable is False

Нам удалось успешно ограничить доступ к выполнению первого случая, обусловив этот случай установкой управляющей переменной enable на False. Выполняемый код — это оператор print, принадлежащий второму оператору case.

Что действительно интересно, так это то, что мы также можем сопоставить структуру:

# declare and initialize a list object
my_list = [1, 2, 3, 4, 5]
# now execute statements depending on itsstructure:
match my_list:
    case [x]:
        print(f"one element: {x}")
    case [x, y]:
        print(f"two elements: {x}, {y}")
    case [x, y, *other]:
        print(f"more than 2 elements: {x}, {y}, {other}")
Output:
more than 2 elements: 1, 2, [3, 4, 5]

Мы даже можем делать разные вещи в зависимости от типа переменной:

# declare and initialize an integer variable,
# then perform some actions based on its value type
num = 32.7
match num:
    case int():
        print("Integer")
    case str():
        print("string")
    case float():
        print("float")
    case _:
        print("something else")
Output:
float

Python попытался сопоставить объект num с одним из этих экземпляров (int, str, float), и, поскольку наш объект num был 32.7, то есть float, Python сопоставил экземпляр float с объектом num, поэтому выполнил соответствующие инструкции, как показано выше. , распечатав float на нашей консоли.

Цель этой статьи состояла в том, чтобы просто продемонстрировать некоторые из основных функций и повысить осведомленность о существовании этой замечательной альтернативы, которая не только помогает нам писать более элегантный и определенно более читаемый код, но и при правильном использовании, это может помочь нам достичь огромного количества вещей.

Это далеко не так просто и элементарно, как другие операторы switch-case, с которыми мы, вероятно, сталкивались, например, в C. Функция Python match-case действительно является очень мощным инструментом сопоставления. Узнавая об этом больше (я все еще учусь и хочу расширить свои знания об этом), я наткнулся на отличную статью на эту тему, которую я горячо рекомендую.

При этом, просто подвожу это, желаю вам быть в безопасности, всегда следить за последними разработками и, как всегда, удачного кодирования! До скорого"!

Дека — инженер-программист, наставник, писатель, а иногда даже учитель. Обладая более чем 12-летним опытом разработки программного обеспечения, он теперь является настоящим сторонником языка программирования Python, а его страстью является помощь людям в оттачивании их навыков Python и программирования в целом. Вы можете связаться с колодой в Linkedin, Facebook, Twitter и Discord: Deck451#6188, а также следить за его публикациями здесь, на Medium.

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord . Заинтересованы в хакинге роста? Ознакомьтесь с разделом Схема.