Введение
Примеры
Используйте то, что предлагает язык: конструкция 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 .