Die meisten Antworten hier sind ziemlich alt, vor allem die akzeptierten, so dass es sich lohnt, sie zu aktualisieren.
Erstens, die offizielle Python-FAQ deckt dies ab und empfiehlt die elif
Kette für einfache Fälle und die dict
für größere oder komplexere Fälle. Sie schlägt auch eine Reihe von visit_
Methoden (ein Stil, der von vielen Server-Frameworks verwendet wird) für einige Fälle:
def dispatch(self, value):
method_name = 'visit_' + str(value)
method = getattr(self, method_name)
method()
In den FAQ heißt es außerdem PEP 275 die geschrieben wurde, um eine offizielle Entscheidung über das Hinzufügen von Switch-Anweisungen im Stil von C zu treffen. Aber dieses PEP wurde eigentlich auf Python 3 verschoben, und es wurde nur offiziell als separater Vorschlag abgelehnt, PEP 3103 . Die Antwort war natürlich nein, aber die beiden PEPs enthalten Links zu zusätzlichen Informationen, falls Sie sich für die Gründe oder die Geschichte interessieren.
Eine Sache, die mehrfach zur Sprache kam (und in PEP 275 zu sehen ist, auch wenn sie als eigentliche Empfehlung herausgeschnitten wurde), ist, dass man, wenn es einen wirklich stört, 8 Zeilen Code zu haben, um 4 Fälle zu behandeln, im Gegensatz zu den 6 Zeilen, die man in C oder Bash hätte, immer dies schreiben kann:
if x == 1: print('first')
elif x == 2: print('second')
elif x == 3: print('third')
else: print('did not place')
Dies wird von PEP 8 nicht gerade gefördert, aber es ist lesbar und nicht zu unidiomatisch.
Seit mehr als einem Jahrzehnt, seit PEP 3103 abgelehnt wurde, gilt das Thema Case-Anweisungen im Stil von C oder sogar der etwas leistungsfähigeren Version in Go als tot; wann immer jemand es auf python-ideas oder -dev anspricht, wird er auf die alte Entscheidung verwiesen.
Die Idee eines vollständigen ML-ähnlichen Musterabgleichs kommt jedoch alle paar Jahre auf, vor allem seit Sprachen wie Swift und Rust sie übernommen haben. Das Problem ist, dass es schwierig ist, ohne algebraische Datentypen viel Nutzen aus dem Pattern Matching zu ziehen. Während Guido der Idee wohlwollend gegenübersteht, hat noch niemand einen Vorschlag gemacht, der gut in Python passt. (Sie können lesen mein Strohmann von 2014 für ein Beispiel). Dies könnte sich ändern mit dataclass
in 3.7 und einige sporadische Vorschläge für ein leistungsfähigeres enum
um Summentypen zu behandeln, oder mit verschiedenen Vorschlägen für verschiedene Arten von anweisungslokalen Bindungen (wie PEP 3150 oder die derzeit diskutierten Vorschläge auf -Ideen). Aber bis jetzt ist das nicht der Fall.
Gelegentlich gibt es auch Vorschläge für ein Matching im Stil von Perl 6, das im Grunde ein Mischmasch aus allem von elif
zu regex zu single-dispatch type-switching.
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 :|