Python Language
Alternative per cambiare dichiarazione da altre lingue
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 :
- Questa soluzione viene offerta come modulo switch disponibile su pypi .