Ricerca…


Osservazioni

Non esiste alcuna istruzione switch in python come scelta del linguaggio design. C'è stato un PEP ( PEP-3103 ) che copre l'argomento che è stato respinto.

È possibile trovare molti elenchi di ricette su come eseguire le proprie istruzioni switch in python, e qui sto cercando di suggerire le opzioni più sensate. Qui ci sono alcuni posti da verificare:

Usa ciò che la lingua offre: il costrutto if / else.

Bene, se vuoi un costrutto switch / case , il modo più semplice per procedere è usare il buon vecchio if / else costrutto:

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

potrebbe sembrare ridondante, e non sempre carino, ma è di gran lunga il modo più efficace per andare, e fa il lavoro:

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

Usa un comando di funzioni

Un altro modo semplice per procedere è creare un dizionario di funzioni:

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

quindi aggiungi una funzione predefinita:

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

e si utilizza il metodo get del dizionario per ottenere la funzione, dato il valore da controllare ed eseguirlo. Se il valore non esiste nel dizionario, viene eseguito 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

puoi anche fare dello zucchero sintattico in modo che l'interruttore appaia più bello:

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

>>> run_switch(1)
one

Usa l'introspezione di classe

Puoi usare una classe per imitare la struttura switch / case. Quanto segue utilizza l'introspezione di una classe (utilizzando la funzione getattr() che risolve una stringa in un metodo associato su un'istanza) per risolvere la parte "caso".

Quindi quel metodo introspettivo viene __call__ al metodo __call__ per sovraccaricare l'operatore () .

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

    __call__ = switch

Quindi, per renderlo più bello, facciamo una sottoclasse della classe SwitchBase (ma potrebbe essere eseguita in una classe), e lì definiamo tutti i case come metodi:

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

quindi possiamo finalmente usarlo:

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

Utilizzando un gestore di contesto

Un altro modo, che è molto leggibile ed elegante, ma molto meno efficiente di una struttura if / else, è di costruire una classe come segue, che leggerà e memorizzerà il valore da confrontare, esponendosi nel contesto come un callable che restituirà true se corrisponde al valore memorizzato:

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

quindi definire i casi è quasi una corrispondenza con il costrutto switch / case reale (esposto all'interno di una funzione di seguito, per renderlo più facile da mostrare):

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

Quindi l'esecuzione sarebbe:

>>> 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow