Szukaj…


Uwagi

Jest instrukcja switch NO w python jako wybór projektu język. PEP ( PEP-3103 ) dotyczy tematu, który został odrzucony.

Możesz znaleźć wiele list przepisów dotyczących wykonywania własnych instrukcji switch w pythonie, a tutaj próbuję zasugerować najbardziej sensowne opcje. Oto kilka miejsc do sprawdzenia:

Użyj tego, co oferuje język: konstrukcja if / else.

Cóż, jeśli potrzebujesz konstrukcji switch / case , najprostszym sposobem jest użycie starej dobrej konstrukcji 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!")

może wydawać się zbędny i nie zawsze ładny, ale jest to zdecydowanie najbardziej skuteczny sposób, i działa:

>>> 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

Skorzystaj ze słownika funkcji

Innym prostym sposobem jest stworzenie słownika funkcji:

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

następnie dodajesz domyślną funkcję:

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

i używasz metody get słownika, aby uzyskać funkcję o wartości do sprawdzenia i uruchomienia. Jeśli wartość nie istnieje w słowniku, uruchamiana jest 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

możesz także zrobić cukier składniowy, aby przełącznik wyglądał ładniej:

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

>>> run_switch(1)
one

Użyj introspekcji klas

Możesz użyć klasy, aby naśladować strukturę przełącznika / obudowy. Poniżej zastosowano introspekcję klasy (za pomocą funkcji getattr() która przekształca ciąg znaków w metodę powiązaną w instancji), aby rozwiązać część „case”.

Następnie ta metoda introspekcji jest aliasowana do metody __call__ celu przeciążenia operatora () .

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

    __call__ = switch

Następnie, aby wyglądał ładniej, SwitchBase klasę SwitchBase (ale można to zrobić w jednej klasie) i tam definiujemy wszystkie case jako metody:

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!')

więc w końcu możemy go użyć:

>>> 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!

Korzystanie z menedżera kontekstu

Innym sposobem, który jest bardzo czytelny i elegancki, ale o wiele mniej wydajny niż struktura if / else, jest zbudowanie takiej klasy, która odczyta i zapisze wartość do porównania, ujawni się w kontekście jako wywołanie, które zwróci true, jeśli pasuje do zapisanej wartości:

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

następnie zdefiniowanie przypadków jest prawie zgodne z rzeczywistą konstrukcją switch / case (udostępnioną w ramach funkcji poniżej, aby ułatwić pokazanie się):

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!')

Wykonanie byłoby więc:

>>> 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 :



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow