Ähnlich wie diese Antwort von abarnert Hier ist eine Lösung speziell für den Anwendungsfall des Aufrufs einer einzigen Funktion für jeden "Fall" in der Weiche, unter Vermeidung der lambda
o partial
für Ultra-Konzisität und kann gleichzeitig mit Schlüsselwortargumenten umgehen:
class switch(object):
NO_DEFAULT = object()
def __init__(self, value, default=NO_DEFAULT):
self._value = value
self._result = default
def __call__(self, option, func, *args, **kwargs):
if self._value == option:
self._result = func(*args, **kwargs)
return self
def pick(self):
if self._result is switch.NO_DEFAULT:
raise ValueError(self._value)
return self._result
Beispiel für die Verwendung:
def add(a, b):
return a + b
def double(x):
return 2 * x
def foo(**kwargs):
return kwargs
result = (
switch(3)
(1, add, 7, 9)
(2, double, 5)
(3, foo, bar=0, spam=8)
(4, lambda: double(1 / 0)) # if evaluating arguments is not safe
).pick()
print(result)
Beachten Sie, dass dies eine Verkettung von Aufrufen ist, d.h. switch(3)(...)(...)(...)
. Setzen Sie keine Kommas dazwischen. Es ist auch wichtig, alles in einen Ausdruck zu packen, weshalb ich zusätzliche Klammern um den Hauptaufruf für die implizite Zeilenfortsetzung gesetzt habe.
Das obige Beispiel löst einen Fehler aus, wenn Sie einen Wert einschalten, der nicht behandelt wird, z. B. switch(5)(1, ...)(2, ...)(3, ...)
. Sie können stattdessen einen Standardwert angeben, z. B. switch(5, default=-1)...
gibt zurück. -1
.
77 Stimmen
PEP zum Thema, verfasst von Guido selbst: PEP 3103
28 Stimmen
@chb In diesem PEP erwähnt Guido nicht, dass if/elif-Ketten auch eine klassische Fehlerquelle sind. Es ist ein sehr anfälliges Konstrukt.
15 Stimmen
Was bei allen Lösungen fehlt, ist die Erkennung von doppelte Fallwerte . Als Fail-Fast-Prinzip kann dies ein größerer Verlust sein als die Leistung oder die Fallthrough-Funktion.
6 Stimmen
switch
ist tatsächlich "vielseitiger" als etwas, das verschiedene feste Werte auf der Grundlage des Wertes eines Eingabeindexes zurückgibt. Sie ermöglicht die Ausführung verschiedener Codestücke. Sie muss nicht einmal einen Wert zurückgeben. Ich frage mich, ob einige der Antworten hier ein guter Ersatz für eine allgemeineswitch
Anweisung oder nur für den Fall, dass Werte zurückgegeben werden, ohne dass die Möglichkeit besteht, allgemeinen Code auszuführen.1 Stimmen
@sancho.s - vereinbart. Wenn Sie nicht zurückkehren oder sich von Ihrem
switch
case
Anweisung dann todo In den übrigen Fällen wird der Code ausgeführt. Das ist eindeutig nicht dasselbe wie eine Sammlung von if/elseifs3 Stimmen
Auf die gleiche Weise erfüllen Syntaxen wie Rubys case...when... (oder Scalas match, Haskells case, Perls given/when) einen allgemeinen Anwendungsfall und bieten eine mächtige Abstraktion. if...elif... ist ein schlechter Ersatz.
1 Stimmen
Pythons Aphorismus, dass "explizit besser ist als implizit" ist das, was Fall-Through in Python nicht zum Standard macht. Ich weiß nicht, ob ich traurig oder glücklich sein soll :|