Аналоги switch в Python

Введение

Примеры

Используйте то, что предлагает язык: конструкция if / else.

Ну, если вы хотите switch / case конструкции, самый простой путь заключается в использовании старых добрых , if / else построить:

 def switch(value):
    if value == 1:
        return "one"
    if value == 2:
        return "two"
    if value == 42:
        return "the answer to the question about life, the universe and everything"
    raise Exception("No case found!")

 

это может выглядеть избыточно, и не всегда красиво, но это самый эффективный способ, и он выполняет свою работу:

 >>> switch(1)
one
>>> switch(2)
two
>>> switch(3)
…
Exception: No case found!
>>> switch(42)
the answer to the question about life the universe and everything 

Используйте набор функций

Еще один простой способ - создать словарь функций:

 switch = {
    1: lambda: 'one',
    2: lambda: 'two',
    42: lambda: 'the answer of life the universe and everything',
}

 

Затем вы добавляете функцию по умолчанию:

 def default_case():
    raise Exception('No case found!')

 

и вы используете метод get из словаря, чтобы получить функцию с заданным значением для проверки и запуска. Если значение не существует в словаре, то default_case запускается.

 >>> switch.get(1, default_case)()
one
>>> switch.get(2, default_case)()
two
>>> switch.get(3, default_case)()
…
Exception: No case found!
>>> switch.get(42, default_case)()
the answer of life the universe and everything

 

Вы также можете сделать немного синтаксического сахара, чтобы переключатель выглядел лучше:

 def run_switch(value):
    return switch.get(value, default_case)()

>>> run_switch(1)
one 

Используйте интроспекцию класса

Вы можете использовать класс для имитации структуры switch / case. Следующий используют интроспекцию класса ( с использованием getattr() функции , которая разрешает строку в связанный метод на примере) , чтобы решить «дело» часть.

Затем этот метод интроспекции является псевдоним для __call__ методы перегружать () оператор.

 class SwitchBase:
    def switch(self, case):
        m = getattr(self, 'case_{}'.format(case), None)
        if not m:
            return self.default
        return m

    __call__ = switch

 

Затем , чтобы сделать его выглядеть лучше, мы создаем подкласс SwitchBase класса (но это может быть сделано в одном классе), и мы определяем все case в качестве методов:

 class CustomSwitcher:
    def case_1(self):
        return 'one'

    def case_2(self):
        return 'two'

    def case_42(self):
        return 'the answer of life, the universe and everything!'

    def default(self):
        raise Exception('Not a case!')

 

так что тогда мы можем наконец использовать его:

 >>> switch = CustomSwitcher()
>>> print(switch(1))
one
>>> print(switch(2))
two
>>> print(switch(3))
…
Exception: Not a case!
>>> print(switch(42))
the answer of life, the universe and everything! 

Использование контекстного менеджера

Другой способ, который очень удобен для чтения и элегантен, но гораздо менее эффективен, чем структура if / else, состоит в том, чтобы создать класс, подобный следующему, который будет считывать и сохранять значение для сравнения, выставлять себя в контексте как вызываемый, который вернет true, если оно соответствует сохраненному значению:

 class Switch:
    def __init__(self, value): 
        self._val = value
    def __enter__(self):
        return self
    def __exit__(self, type, value, traceback):
        return False # Allows traceback to occur
    def __call__(self, cond, *mconds): 
        return self._val in (cond,)+mconds

 

то определение случаев почти совпадение с реальным switch / case конструкции (открытой в функции ниже, чтобы сделать его проще показать):

 def run_switch(value):
    with Switch(value) as case:
        if case(1):
            return 'one'
        if case(2):
            return 'two'
        if case(3):
            return 'the answer to the question about life, the universe and everything'
        # default
        raise Exception('Not a case!')

 

Таким образом, выполнение будет:

 >>> run_switch(1)
one
>>> run_switch(2)
two
>>> run_switch(3)
…
Exception: Not a case!
>>> run_switch(42)
the answer to the question about life, the universe and everything

 

Nota Bene:

  • Это решение предлагается в качестве модуля коммутатора доступны на PyPI .

Синтаксис

Параметры

Примечания