Domanda

Voglio scrivere una funzione in Python che restituisca diversi valori fissi in base al valore di un indice di input.

In altre lingue userei a switch O case istruzione, ma Python non sembra avere un'istruzione switch dichiarazione.Quali sono le soluzioni Python consigliate in questo scenario?

È stato utile?

Soluzione

Potresti usare un dizionario:

def f(x):
    return {
        'a': 1,
        'b': 2,
    }[x]

Altri suggerimenti

Se desideri valori predefiniti puoi utilizzare il dizionario get(key[, default]) metodo:

def f(x):
    return {
        'a': 1,
        'b': 2
    }.get(x, 9)    # 9 is default if x not found

Mi è sempre piaciuto farlo in questo modo

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}[value](x)

Da qui

Oltre ai metodi del dizionario (che mi piacciono molto, a proposito), puoi anche usare if-elif-else per ottenere la funzionalità switch/case/default:

if x == 'a':
    # Do the thing
elif x == 'b':
    # Do the other thing
if x in 'bc':
    # Fall-through by not using elif, but now the default case includes case 'a'!
elif x in 'xyz':
    # Do yet another thing
else:
    # Do the default

Questo ovviamente non è identico a switch/case: non è possibile fallire con la stessa facilità con cui si interrompe la pausa;dichiarazione, ma puoi fare un test più complicato.La sua formattazione è migliore di una serie di if nidificati, anche se funzionalmente è ciò a cui si avvicina di più.

La mia ricetta Python preferita per switch/case è:

choices = {'a': 1, 'b': 2}
result = choices.get(key, 'default')

Breve e semplice per scenari semplici.

Confronta con oltre 11 righe di codice C:

// C Language version of a simple 'switch/case'.
switch( key ) 
{
    case 'a' :
        result = 1;
        break;
    case 'b' :
        result = 2;
        break;
    default :
        result = -1;
}

Puoi anche assegnare più variabili usando le tuple:

choices = {'a': (1, 2, 3), 'b': (4, 5, 6)}
(result1, result2, result3) = choices.get(key, ('default1', 'default2', 'default3'))
class switch(object):
    value = None
    def __new__(class_, value):
        class_.value = value
        return True

def case(*args):
    return any((arg == switch.value for arg in args))

Utilizzo:

while switch(n):
    if case(0):
        print "You typed zero."
        break
    if case(1, 4, 9):
        print "n is a perfect square."
        break
    if case(2):
        print "n is an even number."
    if case(2, 3, 5, 7):
        print "n is a prime number."
        break
    if case(6, 8):
        print "n is an even number."
        break
    print "Only single-digit numbers are allowed."
    break

Test:

n = 2
#Result:
#n is an even number.
#n is a prime number.
n = 11
#Result:
#Only single-digit numbers are allowed.

C'è uno schema che ho imparato dal codice Twisted Python.

class SMTP:
    def lookupMethod(self, command):
        return getattr(self, 'do_' + command.upper(), None)
    def do_HELO(self, rest):
        return 'Howdy ' + rest
    def do_QUIT(self, rest):
        return 'Bye'

SMTP().lookupMethod('HELO')('foo.bar.com') # => 'Howdy foo.bar.com'
SMTP().lookupMethod('QUIT')('') # => 'Bye'

Puoi usarlo ogni volta che devi inviare un token ed eseguire una parte estesa di codice.In una macchina statale lo avresti state_ metodi e invio self.state.Questo passaggio può essere esteso in modo pulito ereditando dalla classe base e definendone una propria do_ metodi.Spesso non lo avrai nemmeno do_ metodi nella classe base.

Modificare:come viene utilizzato esattamente?

In caso di SMTP riceverai HELO dal filo.Il relativo codice (da twisted/mail/smtp.py, modificato per il nostro caso) assomiglia a questo

class SMTP:
    # ...

    def do_UNKNOWN(self, rest):
        raise NotImplementedError, 'received unknown command'

    def state_COMMAND(self, line):
        line = line.strip()
        parts = line.split(None, 1)
        if parts:
            method = self.lookupMethod(parts[0]) or self.do_UNKNOWN
            if len(parts) == 2:
                return method(parts[1])
            else:
                return method('')
        else:
            raise SyntaxError, 'bad syntax'

SMTP().state_COMMAND('   HELO   foo.bar.com  ') # => Howdy foo.bar.com

Riceverai ' HELO foo.bar.com ' (o potresti ottenere 'QUIT' O 'RCPT TO: foo').Questo è tokenizzato in parts COME ['HELO', 'foo.bar.com'].Viene preso il nome effettivo della ricerca del metodo parts[0].

(Il metodo originale è anche chiamato state_COMMAND, perché utilizza lo stesso modello per implementare una macchina a stati, vale a dire getattr(self, 'state_' + self.mode))

Il mio preferito è davvero carino ricetta.Ti piacerà davvero.È il più vicino che abbia mai visto alle effettive dichiarazioni di caso di commutazione, specialmente nelle funzionalità.

class switch(object):
    def __init__(self, value):
        self.value = value
        self.fall = False

    def __iter__(self):
        """Return the match method once, then stop"""
        yield self.match
        raise StopIteration

    def match(self, *args):
        """Indicate whether or not to enter a case suite"""
        if self.fall or not args:
            return True
        elif self.value in args: # changed for v1.5, see below
            self.fall = True
            return True
        else:
            return False

Ecco un esempio:

# The following example is pretty much the exact use-case of a dictionary,
# but is included for its simplicity. Note that you can include statements
# in each suite.
v = 'ten'
for case in switch(v):
    if case('one'):
        print 1
        break
    if case('two'):
        print 2
        break
    if case('ten'):
        print 10
        break
    if case('eleven'):
        print 11
        break
    if case(): # default, could also just omit condition or 'if True'
        print "something else!"
        # No need to break here, it'll stop anyway

# break is used here to look as much like the real thing as possible, but
# elif is generally just as good and more concise.

# Empty suites are considered syntax errors, so intentional fall-throughs
# should contain 'pass'
c = 'z'
for case in switch(c):
    if case('a'): pass # only necessary if the rest of the suite is empty
    if case('b'): pass
    # ...
    if case('y'): pass
    if case('z'):
        print "c is lowercase!"
        break
    if case('A'): pass
    # ...
    if case('Z'):
        print "c is uppercase!"
        break
    if case(): # default
        print "I dunno what c was!"

# As suggested by Pierre Quentel, you can even expand upon the
# functionality of the classic 'case' statement by matching multiple
# cases in a single shot. This greatly benefits operations such as the
# uppercase/lowercase example above:
import string
c = 'A'
for case in switch(c):
    if case(*string.lowercase): # note the * for unpacking as arguments
        print "c is lowercase!"
        break
    if case(*string.uppercase):
        print "c is uppercase!"
        break
    if case('!', '?', '.'): # normal argument passing style also applies
        print "c is a sentence terminator!"
        break
    if case(): # default
        print "I dunno what c was!"
class Switch:
    def __init__(self, value):
        self.value = value

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        return False # Allows a traceback to occur

    def __call__(self, *values):
        return self.value in values


from datetime import datetime

with Switch(datetime.today().weekday()) as case:
    if case(0):
        # Basic usage of switch
        print("I hate mondays so much.")
        # Note there is no break needed here
    elif case(1,2):
        # This switch also supports multiple conditions (in one line)
        print("When is the weekend going to be here?")
    elif case(3,4):
        print("The weekend is near.")
    else:
        # Default would occur here
        print("Let's go have fun!") # Didn't use case for example purposes

Diciamo che non vuoi semplicemente restituire un valore, ma vuoi usare metodi che cambiano qualcosa su un oggetto.Utilizzando l'approccio indicato qui sarebbe:

result = {
  'a': obj.increment(x),
  'b': obj.decrement(x)
}.get(value, obj.default(x))

Quello che succede qui è che Python valuta tutti i metodi nel dizionario.Quindi, anche se il tuo valore è "a", l'oggetto verrà incrementato E diminuito di x.

Soluzione:

func, args = {
  'a' : (obj.increment, (x,)),
  'b' : (obj.decrement, (x,)),
}.get(value, (obj.default, (x,)))

result = func(*args)

Quindi ottieni un elenco contenente una funzione e i suoi argomenti.In questo modo, vengono restituiti solo il puntatore alla funzione e l'elenco degli argomenti, non valutato.'risultato' valuta quindi la chiamata di funzione restituita.

Lascerò semplicemente i miei due centesimi qui.Il motivo per cui in Python non esiste un'istruzione case/switch è perché Python segue il principio "C'è solo un modo giusto per fare qualcosa".Quindi ovviamente potresti inventare vari modi per ricreare la funzionalità switch/case, ma il modo Python per ottenere ciò è il costrutto if/elif.cioè

if something:
    return "first thing"
elif somethingelse:
    return "second thing"
elif yetanotherthing:
    return "third thing"
else:
    return "default thing"

Ho semplicemente sentito che PEP 8 meritava un cenno qui.Una delle cose belle di Python è la sua semplicità ed eleganza.Ciò deriva in gran parte dai principi stabiliti nel PEP 8, tra cui "C'è solo un modo giusto per fare qualcosa"

espandendo l'idea "dict as switch".se desideri utilizzare un valore predefinito per il tuo interruttore:

def f(x):
    try:
        return {
            'a': 1,
            'b': 2,
        }[x]
    except KeyError:
        return 'default'

Se hai un blocco di casi complicato, puoi prendere in considerazione l'utilizzo di una tabella di ricerca del dizionario delle funzioni...

Se non l'hai mai fatto prima, è una buona idea entrare nel tuo debugger e vedere esattamente come il dizionario cerca ciascuna funzione.

NOTA:Fare non usa "()" all'interno della ricerca di case/dizionari o chiamerà ciascuna delle tue funzioni quando viene creato il blocco dizionario/case.Ricordalo perché vuoi chiamare ciascuna funzione solo una volta utilizzando una ricerca in stile hash.

def first_case():
    print "first"

def second_case():
    print "second"

def third_case():
    print "third"

mycase = {
'first': first_case, #do not use ()
'second': second_case, #do not use ()
'third': third_case #do not use ()
}
myfunc = mycase['first']
myfunc()

Se stai cercando un'istruzione extra, come "switch", ho creato un modulo Python che estende Python.È chiamato ESPIA come "Struttura avanzata per Python" ed è disponibile sia per Python 2.x che per Python 3.x.

Ad esempio, in questo caso, un'istruzione switch potrebbe essere eseguita dal seguente codice:

macro switch(arg1):
    while True:
        cont=False
        val=%arg1%
        socket case(arg2):
            if val==%arg2% or cont:
                cont=True
                socket
        socket else:
            socket
        break

che può essere utilizzato in questo modo:

a=3
switch(a):
    case(0):
        print("Zero")
    case(1):
        print("Smaller than 2"):
        break
    else:
        print ("greater than 1")

quindi espy traducilo in Python come:

a=3
while True:
    cont=False
    if a==0 or cont:
        cont=True
        print ("Zero")
    if a==1 or cont:
        cont=True
        print ("Smaller than 2")
        break
    print ("greater than 1")
    break

Non ho trovato la risposta semplice che cercavo da nessuna parte nella ricerca di Google.Ma l'ho capito comunque.È davvero molto semplice.Ho deciso di pubblicarlo, e magari evitare qualche graffio in meno sulla testa di qualcun altro.La chiave è semplicemente "in" e tuple.Ecco il comportamento dell'istruzione switch con fall-through, incluso il fall-through RANDOM.

l = ['Dog', 'Cat', 'Bird', 'Bigfoot',
     'Dragonfly', 'Snake', 'Bat', 'Loch Ness Monster']

for x in l:
    if x in ('Dog', 'Cat'):
        x += " has four legs"
    elif x in ('Bat', 'Bird', 'Dragonfly'):
        x += " has wings."
    elif x in ('Snake',):
        x += " has a forked tongue."
    else:
        x += " is a big mystery by default."
    print(x)

print()

for x in range(10):
    if x in (0, 1):
        x = "Values 0 and 1 caught here."
    elif x in (2,):
        x = "Value 2 caught here."
    elif x in (3, 7, 8):
        x = "Values 3, 7, 8 caught here."
    elif x in (4, 6):
        x = "Values 4 and 6 caught here"
    else:
        x = "Values 5 and 9 caught in default."
    print(x)

Fornisce:

Dog has four legs
Cat has four legs
Bird has wings.
Bigfoot is a big mystery by default.
Dragonfly has wings.
Snake has a forked tongue.
Bat has wings.
Loch Ness Monster is a big mystery by default.

Values 0 and 1 caught here.
Values 0 and 1 caught here.
Value 2 caught here.
Values 3, 7, 8 caught here.
Values 4 and 6 caught here
Values 5 and 9 caught in default.
Values 4 and 6 caught here
Values 3, 7, 8 caught here.
Values 3, 7, 8 caught here.
Values 5 and 9 caught in default.

Ho scoperto che una struttura di commutazione comune:

switch ...parameter...
case p1: v1; break;
case p2: v2; break;
default: v3;

può essere espresso in Python come segue:

(lambda x: v1 if p1(x) else v2 if p2(x) else v3)

o formattato in modo più chiaro:

(lambda x:
     v1 if p1(x) else
     v2 if p2(x) else
     v3)

Invece di essere un'istruzione, la versione Python è un'espressione, che restituisce un valore.

Le soluzioni che utilizzo:

Una combinazione di 2 delle soluzioni pubblicate qui, che è relativamente facile da leggere e supporta le impostazioni predefinite.

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}.get(whatToUse, lambda x: x - 22)(value)

Dove

.get('c', lambda x: x - 22)(23)

guarda su "lambda x: x - 2" nel dict e lo usa con x=23

.get('xxx', lambda x: x - 22)(44)

non lo trova nel dict e utilizza il valore predefinito "lambda x: x - 22" con x=44.

# simple case alternative

some_value = 5.0

# this while loop block simulates a case block

# case
while True:

    # case 1
    if some_value > 5:
        print ('Greater than five')
        break

    # case 2
    if some_value == 5:
        print ('Equal to five')
        break

    # else case 3
    print ( 'Must be less than 5')
    break

La maggior parte delle risposte qui sono piuttosto vecchie, e soprattutto quelle accettate, quindi sembra che valga la pena aggiornarle.

Innanzitutto, il funzionario Domande frequenti su Python copre questo e raccomanda il elif catena per casi semplici e il dict per casi più grandi o più complessi.Suggerisce anche una serie di visit_ metodi (uno stile utilizzato da molti framework server) per alcuni casi:

def dispatch(self, value):
    method_name = 'visit_' + str(value)
    method = getattr(self, method_name)
    method()

Le FAQ menzionano anche PEP 275, che è stato scritto per ottenere una decisione ufficiale una volta per tutte sull'aggiunta di istruzioni switch in stile C.Ma quel PEP è stato in realtà rinviato a Python 3, ed è stato ufficialmente respinto solo come proposta separata, PEP 3103.La risposta, ovviamente, è stata no, ma i due PEP hanno collegamenti a informazioni aggiuntive se sei interessato alle ragioni o alla storia.


Una cosa che è emersa più volte (e può essere vista in PEP 275, anche se è stata tagliata come una vera raccomandazione) è che se sei davvero infastidito dall'avere 8 righe di codice per gestire 4 casi, invece di...le 6 righe che avresti in C o Bash, puoi sempre scrivere questo:

if x == 1: print('first')
elif x == 2: print('second')
elif x == 3: print('third')
else: print('did not place')

Questo non è esattamente incoraggiato dal PEP 8, ma è leggibile e non troppo unidiomatico.


Nel corso degli oltre dieci anni successivi al rifiuto del PEP 3103, la questione delle dichiarazioni dei casi in stile C, o anche della versione leggermente più potente in Go, è stata considerata morta;ogni volta che qualcuno ne parla su python-ideas o -dev, viene fatto riferimento alla vecchia decisione.

Tuttavia, l’idea di un pattern match completo in stile ML nasce ogni pochi anni, soprattutto da quando linguaggi come Swift e Rust l’hanno adottata.Il problema è che è difficile sfruttare al meglio la corrispondenza dei modelli senza tipi di dati algebrici.Anche se Guido è stato favorevole all'idea, nessuno ha ancora avuto una proposta che si adatti molto bene a Python.(Puoi leggere il mio uomo di paglia del 2014 per un esempio.) Questo potrebbe cambiare con dataclass in 3.7 e alcune sporadiche proposte per una versione più potente enum per gestire i tipi di somma, o con varie proposte per diversi tipi di collegamenti locali tra istruzioni (come PEP3150, ovvero l'insieme di proposte attualmente in discussione su -ideas).Ma finora non è stato così.

Occasionalmente ci sono anche proposte per l'abbinamento in stile Perl 6, che è fondamentalmente un miscuglio di tutto, da elif per regex al cambio di tipo a invio singolo.

def f(x):
    dictionary = {'a':1, 'b':2, 'c':3}
    return dictionary.get(x,'Not Found') 
##Returns the value for the letter x;returns 'Not Found' if x isn't a key in the dictionary

mi è piaciuto La risposta di Mark Bies

Dal momento che x La variabile deve essere utilizzata due volte, ho modificato le funzioni lambda in senza parametri.

Devo scappare results[value](value)

In [2]: result = {
    ...:   'a': lambda x: 'A',
    ...:   'b': lambda x: 'B',
    ...:   'c': lambda x: 'C'
    ...: }
    ...: result['a']('a')
    ...: 
Out[2]: 'A'

In [3]: result = {
    ...:   'a': lambda : 'A',
    ...:   'b': lambda : 'B',
    ...:   'c': lambda : 'C',
    ...:   None: lambda : 'Nothing else matters'

    ...: }
    ...: result['a']()
    ...: 
Out[3]: 'A'

Modificare: Ho notato che posso usare None digitare con i dizionari.Quindi questo emulerebbe switch ; case else

Soluzione per eseguire le funzioni:

result = {
    'case1':     foo1, 
    'case2':     foo2,
    'case3':     foo3,
    'default':   default,
}.get(option)()

dove foo1(), foo2(), foo3() e default() sono funzioni

def f(x):
     return 1 if x == 'a' else\
            2 if x in 'bcd' else\
            0 #default

Breve e facile da leggere, ha un valore predefinito e supporta le espressioni sia nelle condizioni che nei valori restituiti.

Tuttavia è meno efficace della soluzione con dizionario.Ad esempio, Python deve esaminare tutte le condizioni prima di restituire il valore predefinito.

Penso che il modo migliore sia farlo usa gli idiomi del linguaggio Python per mantenere il tuo codice testabile.Come mostrato nelle risposte precedenti, utilizzo i dizionari per sfruttare le strutture e il linguaggio Python e mantenere il codice "case" isolato in diversi metodi.Sotto c'è una classe, ma puoi usare direttamente un modulo, globali e funzioni.La classe ha metodi that può essere testato con l'isolamento.A seconda delle tue esigenze, puoi giocare anche con metodi e attributi statici.

class ChoiceManager:

    def __init__(self):
        self.__choice_table = \
        {
            "CHOICE1" : self.my_func1,
            "CHOICE2" : self.my_func2,
        }

    def my_func1(self, data):
        pass

    def my_func2(self, data):
        pass

    def process(self, case, data):
        return self.__choice_table[case](data)

ChoiceManager().process("CHOICE1", my_data)

È possibile sfruttare questo metodo utilizzando anche le classi come chiavi di "__choice_table".In questo modo puoi evitare è un abuso di casi e mantenere tutto pulito e testabile.

Supponiamo che tu debba elaborare molti messaggi o pacchetti dalla rete o dal tuo MQ.Ogni pacchetto ha una propria struttura ed un proprio codice di gestione (in modo generico).Con il codice sopra è possibile fare qualcosa del genere:

class PacketManager:

    def __init__(self):
        self.__choice_table = \
        {
            ControlMessage : self.my_func1,
            DiagnosticMessage : self.my_func2,
        }

    def my_func1(self, data):
        # process the control message here
        pass

    def my_func2(self, data):
        # process the diagnostic message here
        pass

    def process(self, pkt):
        return self.__choice_table[pkt.__class__](pkt)

pkt = GetMyPacketFromNet()
PacketManager().process(pkt)


# isolated test or isolated usage example
def test_control_packet():
    p = ControlMessage()
    PacketManager().my_func1(p)

COSÌ la complessità non è diffusa nel flusso del codice ma è resa nella struttura del codice.

Espansione La risposta di Greg Hewgill - Possiamo incapsulare la soluzione dizionario utilizzando un decoratore:

def case(callable):
    """switch-case decorator"""
    class case_class(object):
        def __init__(self, *args, **kwargs):
            self.args = args
            self.kwargs = kwargs

        def do_call(self):
            return callable(*self.args, **self.kwargs)

return case_class

def switch(key, cases, default=None):
    """switch-statement"""
    ret = None
    try:
        ret = case[key].do_call()
    except KeyError:
        if default:
            ret = default.do_call()
    finally:
        return ret

Questo può quindi essere utilizzato con il @case-decoratore

@case
def case_1(arg1):
    print 'case_1: ', arg1

@case
def case_2(arg1, arg2):
    print 'case_2'
    return arg1, arg2

@case
def default_case(arg1, arg2, arg3):
    print 'default_case: ', arg1, arg2, arg3

ret = switch(somearg, {
    1: case_1('somestring'),
    2: case_2(13, 42)
}, default_case(123, 'astring', 3.14))

print ret

La buona notizia è che questo è già stato fatto NeoPySwitch-modulo.Installalo semplicemente utilizzando pip:

pip install NeoPySwitch

Una soluzione che tendo ad utilizzare che fa uso anche di dizionari è:

def decision_time( key, *args, **kwargs):
    def action1()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action2()
        """This function is a closure - and has access to all the arguments"""
        pass
    def action3()
        """This function is a closure - and has access to all the arguments"""
        pass

   return {1:action1, 2:action2, 3:action3}.get(key,default)()

Questo ha il vantaggio che non tenta di valutare le funzioni ogni volta e devi solo assicurarti che la funzione esterna riceva tutte le informazioni di cui hanno bisogno le funzioni interne.

puoi usare un dict inviato:

#!/usr/bin/env python


def case1():
    print("This is case 1")

def case2():
    print("This is case 2")

def case3():
    print("This is case 3")


token_dict = {
    "case1" : case1,
    "case2" : case2,
    "case3" : case3,
}


def main():
    cases = ("case1", "case3", "case2", "case1")
    for case in cases:
        token_dict[case]()


if __name__ == '__main__':
    main()

Produzione:

This is case 1
This is case 3
This is case 2
This is case 1

Semplice, non testato;ogni condizione viene valutata in modo indipendente:non c'è fall-through, ma vengono valutati tutti i casi (sebbene l'espressione da attivare venga valutata solo una volta), a meno che non sia presente un'istruzione break.Per esempio,

for case in [expression]:
    if case == 1:
        print(end='Was 1. ')

    if case == 2:
        print(end='Was 2. ')
        break

    if case in (1, 2):
        print(end='Was 1 or 2. ')

    print(end='Was something. ')

stampe Was 1. Was 1 or 2. Was something. (Dannazione!Perché non posso avere spazi bianchi finali nei blocchi di codice in linea?) Se expression valuta a 1, Was 2. Se expression valuta a 2, O Was something. Se expression valuta qualcos'altro.

Definizione:

def switch1(value, options):
  if value in options:
    options[value]()

ti consente di utilizzare una sintassi abbastanza semplice, con i casi raggruppati in una mappa:

def sample1(x):
  local = 'betty'
  switch1(x, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye," + local),
      print("!")),
    })

Ho continuato a provare a ridefinire lo switch in un modo che mi permettesse di sbarazzarmi di "lambda:", ma ho rinunciato.Modificando la definizione:

def switch(value, *maps):
  options = {}
  for m in maps:
    options.update(m)
  if value in options:
    options[value]()
  elif None in options:
    options[None]()

Mi ha permesso di mappare più casi sullo stesso codice e di fornire un'opzione predefinita:

def sample(x):
  switch(x, {
    _: lambda: print("other") 
    for _ in 'cdef'
    }, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye,"),
      print("!")),
    None: lambda: print("I dunno")
    })

Ogni caso replicato deve trovarsi nel proprio dizionario;switch() consolida i dizionari prima di cercare il valore.È ancora più brutto di quanto vorrei, ma ha l'efficienza di base di utilizzare una ricerca con hash sull'espressione, anziché un ciclo attraverso tutte le chiavi.

Se non ti preoccupa perdere l'evidenziazione della sintassi all'interno delle suite di casi, puoi procedere come segue:

exec {
    1: """
print ('one')
""", 
    2: """
print ('two')
""", 
    3: """
print ('three')
""",
}.get(value, """
print ('None')
""")

Dove value è il valore.In C, questo sarebbe:

switch (value) {
    case 1:
        printf("one");
        break;
    case 2:
        printf("two");
        break;
    case 3:
        printf("three");
        break;
    default:
        printf("None");
        break;
}

Possiamo anche creare una funzione di supporto per fare ciò:

def switch(value, cases, default):
    exec cases.get(value, default)

Quindi possiamo usarlo in questo modo per l'esempio con uno, due e tre:

switch(value, {
    1: """
print ('one')
    """, 
    2: """
print ('two')
    """, 
    3: """
print ('three')
    """,
}, """
print ('None')
""")
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top