- Операторы switch в Python 3.10
- Старый способ выполнения условных операций.
- Примечание:
- Как реализовать оператор switch-case в Python
- Оператор switch
- Как реализовать оператор switch в Python
- Сопоставление ключей словаря для функций
- Преимущество подхода Python для реализации switch
- Реализация Switch-Case в Python
- Реализация Switch-Case в Python
- 1. Реализация Python Switch Case с использованием словаря
- 2. С динамическими функциями
- Вывод
Операторы switch в Python 3.10
Python 3.10 все еще находится на стадии альфа-тестирования, но в нем появятся некоторые новые интересные функции. В этой статье мы рассмотрим один из них — операторы switch, официально известные как сопоставление структурных шаблонов.
Оператор switch обычно встречается в большинстве языков программирования и обеспечивают более аккуратный способ реализации условной логики. Он пригодятся, когда нужно оценить множество условий.
Сегодня мы увидим, как его использовать, и сравним различия кода с более традиционным подходом.
Старый способ выполнения условных операций.
Первый — это ваш стандартный оператор if-elif-else , а второй — использование словарных сопоставлений «ключ-значение», чтобы полностью избежать операторов if .
Перво-наперво нам нужен код. Мы объявим функцию get_mood(day: str) -> str , которая возвращает строку, значение которой зависит от входного параметра.
Глупая маленькая функция, но подойдет для демонстрационных целей.
Реализуем это по классической if-методологии. Вот код:
def get_mood(day): if day == 'Monday': return 'Oh. ' if day == 'Thursday': return 'Getting close!' if day == 'Friday': return 'Almost there!' if day == 'Saturday' or day == 'Sunday': return 'Weekend. ' return 'Meh. ' print(get_mood(day='Monday')) # Oh. print(get_mood(day='Wednesday')) # Meh. print(get_mood(day='Friday')) # Almost there! print(get_mood(day='Sunday')) # Weekend.
Здесь нет ничего нового или революционного. Код прост для понимания, но слишком подробен, особенно когда несколько значений могут удовлетворять одному условию.
Мы можем «улучшить» или немного изменить ситуацию, полностью избегая операторов if и написав функцию в виде сопоставлений «ключ-значение». Это также включает блок try except для установки возвращаемого значения по умолчанию.
def get_mood(day): mappings = < 'Monday': 'Oh. ', 'Thursday': 'Getting close!', 'Friday': 'Almost there!', 'Saturday': 'Weekend. ', 'Sunday': 'Weekend. ' >try: return mappings[day] except KeyError: return 'Meh. ' print(get_mood(day='Monday')) # Oh. print(get_mood(day='Wednesday')) # Meh. print(get_mood(day='Friday')) # Almost there! print(get_mood(day='Sunday')) # Weekend.
Как видите, результаты идентичны, но мы не использовали условные операторы. Оба подхода будут работать нормально, но в Python всегда отсутствовал специальный оператор switch .
Теперь давайте исправим это с помощью оператора switch в Python 3.10.
Согласно официальной документации:
Было добавлено структурное сопоставление с образцом в форме оператора соответствия и операторов case шаблонов со связанными действиями. Шаблоны состоят из последовательностей, отображений, примитивных типов данных, а также экземпляров классов. Сопоставление с образцом позволяет программам извлекать информацию из сложных типов данных, переходить к структуре данных и применять определенные действия на основе различных форм данных.
Ради простоты, сегодня мы остановимся на основах и исследуем все, что может предложить сопоставление структурных шаблонов, в другой раз.
Вернемся к нашей функции get_mood() и перепишем ее с синтаксисом, похожим на оператор switch. В отличие от многих других языков программирования, Python использует ключевое слово match вместо switch. Ключевое слово case идентично.
def get_mood(day): match day: case 'Monday': return 'Oh. ' case 'Thursday': return 'Getting close!' case 'Friday': return 'Almost there!' case 'Saturday' | 'Sunday': return 'Weekend. ' case _: return 'Meh. ' print(get_mood(day='Monday')) # Oh. print(get_mood(day='Wednesday')) # Meh. print(get_mood(day='Friday')) # Almost there! print(get_mood(day='Sunday')) # Weekend.
- Используйте ключевое слово case для оценки условия (case ‘Monday’ идентично if day == ‘Monday’)
- Разделите несколько условий с помощью оператора вертикальной черты — | — например, если два входных значения должны привести к одному и тому же возвращаемому значению
- Используйте оператор подчеркивания — _ -, чтобы указать действие по умолчанию.
Примечание:
- Python 3.10 принесет много интересных функций, но он все еще находится в альфа-версии. Поскольку он не готов к производству, не рекомендуется устанавливать его в качестве версии Python по умолчанию.
Как реализовать оператор switch-case в Python
Оператор switch-case — это мощная функциональная возможность языка программирования, которая позволяет разработчику управлять ходом выполнения всей программы в зависимости от значения переменной или результата вычисления выражения.
Обычно же эта конструкция языка используется для выполнения различных блоков кода в зависимости от значения некоторой переменной во время выполнения программы. Вот пример использования оператора switch в языке Java.
public static void switch_demo(String[] args) < int month = 8; String monthString; switch(month) < case 1: monthString = "January"; break; case 2: monthString = "February"; break; case 3: monthString = "March"; break; case 4: monthString = "April"; break; case 5: monthString = "May"; break; case 6: monthString = "June"; break; case 7: monthString = "July"; break; case 8: monthString = "August"; break; case 9: monthString = "September"; break; case 10: monthString = "October"; break; case 11: monthString = "November"; break; case 12: monthString = "December"; break; default: monthString = "Invalid mont"; break; >System.out.println(monthString); >
Вот как работает этот код:
- Компилятор создает таблицу переходов для оператора switch case .
- Переменная/выражение в скобках после ключевого слова switch вычисляется один раз.
- Оператор switch ищет вычисленное значение переменной/выражения в таблице переходов и после этого непосредственно определяет, какой блок кода выполнить.
- Если совпадений не найдено, выполняется код по умолчанию, помещенный в блок кода default .
В приведенном выше примере, в зависимости от значения переменной month , в потоке стандартного вывода будет отображаться соответствующее сообщение. В этом случае, поскольку month = 8 , то будет выведено сообщение August .
Оператор switch
И хотя в таких популярных языках, таких как Java и PHP, есть собственный оператор switch , то вы наверное быть удивлены, узнав, что в языке Python его нет. Поэтому у вас, наверняка, уже возникал соблазн написать серию блоков кода if-else-if, используя условный оператор if для каждого значения в case оператора switch .
Тем не менее из-за использования этой таблицы переходов оператор switch работает намного быстрее, чем “лестница” из if-else-if . Вместо того, чтобы последовательно оценивать каждое условие после оператора if , ему нужно только один раз вычислить значение переменной/выражения в switch и непосредственно перейти к соответствующей ветви кода для его выполнения.
Как реализовать оператор switch в Python
Рассмотрим способ реализации оператора switch на языке Python, который заключается в использовании механизма сопоставления словарей. Также этот тип данных более известен как ассоциативные массивы, которые реализуют операцию простого сопоставления «ключ-значение».
В следующем примере мы создаем словарь switcher , который будет хранить все значения, помещаемые после ключевого слова case .
def switch_demo(argument): switcher = < 1: "January", 2: "February", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "August", 9: "September", 10: "October", 11: "November", 12: "December" >print switcher.get(argument, "Invalid month")
В приведенном выше примере, когда вы передаете значение в качестве аргумента функции switch_demo , оно сопоставляется с ключами словаря switcher . И если совпадение будет найдено, то в терминале будет выведено связанное с ним значение (месяц), в противном случае печатается строка по умолчанию «Invalid month». Строка по умолчанию помогает реализовать инструкцию default case оператора switch .
Сопоставление ключей словаря для функций
Теперь становится интереснее. Как известно, значениями словаря Python могут быть данные любого типа. Таким образом, нам не нужно ограничиваться использованием констант (целых чисел, строк), мы можем использовать в качестве значений словаря как имена функций, так и лямбда-выражения.
Теперь с учетом вышесказанного, мы можем переписать наш пример реализации оператора switch , используя словарь с именами функций, используемых в качестве значений. В данном случае switch – это словарь имён функций, а не строк.
def one(): return "January" def two(): return "February" def three(): return "March" def four(): return "April" def five(): return "May" def six(): return "June" def seven(): return "July" def eight(): return "August" def nine(): return "September" def ten(): return "October" def eleven(): return "November" def twelve(): return "December" def numbers_to_months(argument): switcher = < 1: one, 2: two, 3: three, 4: four, 5: five, 6: six, 7: seven, 8: eight, 9: nine, 10: ten, 11: eleven, 12: twelve ># Получим функцию из словаря switcher func = switcher.get(argument, lambda: "Invalid month") # Вызовем полученную функцию print func()
Хотя указанные выше функции довольно просты и возвращают только строки, вы можете использовать этот подход для выполнения более сложных блоков кода внутри каждой функции.
Фактически, если вы вызываете методы для объектов, вы даже можете использовать специальный метод для диспетчеризации, чтобы динамически определять, какую функцию нужно вызывать во время выполнения.
class Switcher(object): def numbers_to_months(self, argument): """Dispatch method""" method_name = 'month_' + str(argument) # Получим соответствующий метод у объекта self. По умолчанию передадим lambda функцию. method = getattr(self, method_name, lambda: "Invalid month") # Вызовем метод и вернем его результат return method() def month_1(self): return "January" def month_2(self): return "February" def month_3(self): return "March" .
Исходя из значения переданного аргумента нативная функция getattr() будет возвращать методы объекта с определенным именем.
Input: a=Switcher() Input: a.numbers_to_months(1) Output: January
Преимущество подхода Python для реализации switch
Поскольку можно изменять словари Python во время выполнения кода: то есть добавлять, удалять или обновлять их элементы, а точнее пары ключ-значение. То можно легко изменить сам оператор switch в процессе выполнения программы, как говориться “на лету”. Рассмотрим следующий пример кода:
def zero(): return "zero" def one(): return "one" def two(): return "two" switcher = < 0: zero, 1: one, 2: two >def numbers_to_strings(argument): # Получим функцию из словаря switcher func = switcher.get(argument, "nothing") # вызовем соответствующую функции return func()
Результатом его выполнения будет вывод следующих значений в терминале.
Input: numbers_to_strings(1) Output: One Input: switcher[1]=two # тут мы изменили поведение для определенного case в switcher Input: numbers_to_strings(1) Output: Two
Switch-case — очень полезная конструкция кода, которая не только обеспечивает лучшую производительность, чем использование последовательности операторов if-else , но и предоставляет разработчику более управляемый и гибкий код. Если вы почувствовали себя ограниченным в своих действия из-за отсутствия оператора switch в Python, надеюсь, эта статья поможет реализовать его в ваших программах.
Реализация Switch-Case в Python
Python не поддерживает операторы switch-case. Было предложение ввести операторы Python switch case в PEP-3103, но оно было отклонено, поскольку не добавляет слишком большого значения.
Мы можем легко реализовать логику операторов switch-case, используя операторы if-else-elif. Однако мы можем реализовать поведение типа switch, используя собственный код.
Реализация Switch-Case в Python
Есть два способа реализовать в Python поведение switch-case.
1. Реализация Python Switch Case с использованием словаря
Мы можем создать словарь, в котором ключ будет регистром, а значение будет результатом. Мы вызовем метод словаря get() со значением по умолчанию, чтобы реализовать сценарий, когда нет подходящего случая.
Допустим, у нас есть следующий блок if-else.
print("Choices:\n 1 - Email\n 2 - SMS\n 3 - Push Notification") x = input("Please enter your choice:\n") x = int(x) if x is 1: print('sending email') elif x is 2: print('sending sms') elif x is 3: print('sending push notification') else: print('wrong choice')
Теперь мы хотим преобразовать его в поведение switch-case с помощью словаря.
print("Choices:\n 1 - Email\n 2 - SMS\n 3 - Push Notification") x = input("Please enter your choice:\n") x = int(x) choices_dict = print(choices_dict.get(x, 'wrong choice'))
2. С динамическими функциями
Вышеупомянутая реализация работает с простыми операторами печати. Но в большинстве случаев мы выполняем какой-либо метод в блоках if-else, и тогда словарь не будет работать как замена switch-case.
Допустим, у нас есть следующий блок if-else для выполнения некоторой операции с входным целым числом.
import math x = input("Please enter an integer:\n") x = int(x) print("Choices:\n 1 - Square\n 2 - Cube\n 3 - Square Root") choice = input("Please enter your choice:\n") choice = int(choice) if choice is 1: print(math.pow(x, 2)) elif choice is 2: print(math.pow(x, 3)) elif choice is 3: print(math.sqrt(x))
Мы можем создать динамический метод для реализации поведения типа switch-case.
import math x = input("Please enter an integer:\n") x = int(x) print("Choices:\n 1 - Square\n 2 - Cube\n 3 - Square Root") choice = input("Please enter your choice:\n") choice = int(choice) def switch_func(value, i): return < 1: lambda val: math.pow(val, 2), 2: lambda val: math.pow(val, 3), 3: lambda val: math.sqrt(val), >.get(value)(i) print(switch_func(choice, x))
Здесь выбор сопоставляется с ключом словаря, а входное целое число сопоставляется с лямбда-функцией. Наконец, результат лямбда-функции возвращается из вызова switch_func().
Вывод
Хорошо поэкспериментировать с реализацией операторов switch-case. Но это очень сбивает с толку, и мы не можем реализовать сложные сценарии с несколькими операторами в блоке if-else. Итак, придерживайтесь простых старых операторов if-else и делайте свой код простым и легким для чтения.