Warum Python, Go und Rust keinen ternären Operator verwenden
Lukas Schneider
DevOps Engineer · Leapcell

Beim Programmieren müssen wir oft bedingte Urteile fällen und basierend auf dem Ergebnis auswählen, verschiedene Codeblöcke auszuführen. In vielen Programmiersprachen ist die gebräuchlichste Methode dafür der ternäre Operator. Python unterstützt den ternären Operator jedoch nicht. Interessanterweise unterstützen auch zwei der beliebtesten aufstrebenden Sprachen, Go und Rust, ihn nicht!
Warum unterstützt Python den ternären Operator nicht? Dieser Artikel analysiert hauptsächlich den Prozess hinter Pythons Design von bedingter Syntax und erklärt, warum es eine einzigartige Implementierung übernommen hat. Gleichzeitig untersuchen wir, warum andere Sprachen den traditionellen ternären Operator ebenfalls aufgegeben haben.
Was ist der ternäre Operator?
Der ternäre Operator bezieht sich normalerweise auf ?: mit der Syntax in der Form: condition ? expression1 : expression2. Wenn die Bedingung wahr ist, wird sie zu expression1 ausgewertet; andernfalls wird sie zu expression2 ausgewertet.
Die vereinfachte Form a ? b : c kann als "wenn Bedingung a wahr ist, dann gib b zurück, andernfalls gib c zurück" gelesen werden.
Der ternäre Operator ist eine vereinfachte Version einer Standard-If-Else-Struktur und wird üblicherweise verwendet, um bedingte Prüfungen durchzuführen und Werte in einer einzigen Anweisung zurückzugeben.
// Reguläre if-else if (a > b) { result = x; } else { result = y; } // Vereinfachte Version result = a > b ? x : y;
Viele Programmiersprachen haben dieses Syntaxdesign übernommen, darunter C, C#, C++, Java, JavaScript, PHP, Perl, Ruby, Swift und mehr. Ohne Zweifel ist dies seit langem der Mainstream-Designansatz in Programmiersprachen (und ist es auch heute noch).
Diese Syntax ist sehr prägnant und effizient, und ihre Lesbarkeit ist ebenfalls stark (sobald man sich daran gewöhnt hat), was sie ziemlich beliebt macht.
Allerdings ist sie nicht fehlerfrei. Python ist der bekannteste Herausforderer dieses Designansatzes. Lassen Sie uns untersuchen, warum Python einen anderen Weg gewählt hat.
Die Python-Community-Abstimmung
Python wurde 1991 veröffentlicht, aber für die nächsten 15 Jahre hatte es nur If-Else-Syntax für Bedingungen und unterstützte keine ternären Operatoren oder andere bedingte Ausdrücke. Bevor bedingte Ausdrücke im Jahr 2006 eingeführt wurden, führte die Community eine lange und komplizierte Debatte – man kann sagen, dass dies eine schwer zu finalisierende Syntaxfunktion war.
Ursprünglich wurde aufgrund wiederholter Bitten um die Hinzufügung eines If-Dann-Else (ternären) Ausdrucks im Februar 2003 PEP 308 – Bedingte Ausdrücke vorgeschlagen. Ziel war es, eine Lösung auszuwählen, die die Mehrheit der Community unterstützen könnte.
Bald entstanden mehrere Vorschläge innerhalb der Community, abgesehen von einer kleinen Gruppe, die es vorzog, nichts zu tun:
(1) Zeichenbasierter ternärer Operator
Dies ist der konventionelle ternäre Operator mit der bereits erwähnten Syntax:
<condition> ? <expression1> : <expression2>
Dieser Vorschlag war recht beliebt, und einige Entwickler reichten sogar Implementierungscode ein. Guido lehnte ihn jedoch aus zwei Gründen ab: Der Doppelpunkt hatte in Python bereits viele Verwendungen (auch wenn Mehrdeutigkeiten unwahrscheinlich waren, da das Fragezeichen einen passenden Doppelpunkt erfordert); und für diejenigen, die mit C-ähnlichen Sprachen nicht vertraut sind, könnte die Syntax schwer zu verstehen sein.
(2) Konstruiert mit vorhandenen und neuen Schlüsselwörtern
Einführung eines neuen Stichworts then und Kombination mit dem vorhandenen else:
<condition> then <expression1> else <expression2>
Seine Vorteile waren Klarheit, keine Notwendigkeit für Klammern, keine Änderung der Semantik vorhandener Schlüsselwörter, geringes Risiko, mit einer Anweisung verwechselt zu werden, und keine Überladung des Doppelpunkts. Der Nachteil war, dass die Hinzufügung eines neuen Schlüsselworts kostspielig in der Implementierung wäre.
(3) Andere Vorschläge
Diese waren im Geiste ähnlich dem zweiten Ansatz, erhielten aber nicht so viel Unterstützung:
(if <condition>: <expression1> else: <expression2>) <condition> and <expression1> else <expression2> <expression1> if <condition> else <expression2> cond(<condition>, <expression1>, <expression2>)
Insbesondere ist das Format (if <condition>: <expression1> else: <expression2>) eine abgeflachte Version der regulären If-Else-Syntax, leicht verständlich, erfordert aber Klammern. Dies kann zu Verwirrung mit Generatorausdrücken führen und erfordert eine spezielle Behandlung des Doppelpunkts durch den Interpreter.
Ebenfalls bemerkenswert ist <expression1> if <condition> else <expression2>, die ursprünglich empfohlene Version in früheren Versionen von PEP 308. Einige Leute mochten diese Form jedoch nicht, weil die Bedingung nicht am Anfang stand. Außerdem ist es bei einer langen expression1 leicht, die Bedingung völlig zu übersehen.
Hier waren alle zur Abstimmung stehenden Optionen:
A. x if C else y
B. if C then x else y
C. (if C: x else: y)
D. C ? x : y
E. C ? x ! y
F. cond(C, x, y)
G. C ?? x || y
H. C then x else y
I. x when C else y
J. C ? x else y
K. C -> x else y
L. C -> (x, y)
M. [x if C else y]
N. ifelse C: x else y
O. <if C then x else y>
P. C and x else y
Q. Sonstige Stimmen
Im Allgemeinen wollten Entwickler eine Form von If-Dann-Else-Ausdruck einführen, aber nach der Abstimmung erhielt keine Option eine klare Mehrheit. Die Streitigkeiten kochten darauf hinaus: ob Zeichen verwendet werden sollten, Schlüsselwörter wiederverwendet werden sollten, Klammern wiederverwendet werden sollten, neue Schlüsselwörter eingeführt werden sollten oder neue Syntax hinzugefügt werden sollte...
Da die Stimmen zu zersplittert waren, wurde der PEP damals abgelehnt. Der PEP besagte: "Eines der Designprinzipien von Python ist die Beibehaltung des Status quo angesichts von Unsicherheit."
Probleme bei der Verwendung von and-or zur bedingten Auswahl
Die oben genannte Abstimmung fand im März 2004 statt, aber die Diskussionen über dieses Thema starben nach der Ablehnung von PEP 308 nicht ab. Entwickler suchten immer noch nach einer prägnanten Möglichkeit, if-else zu ersetzen.
Im September 2005 schlug jemand auf der Mailingliste die Änderung der Logik der and- und or-Operatoren in Python 3.0 vor. Die Idee war, and und or zu vereinfachen, so dass sie immer boolesche Werte zurückgeben würden, anstatt den zuletzt ausgewerteten Operanden zurückzugeben.
Der Grund für diesen Vorschlag war, dass der Autor die Form <condition> and <expression1> or <expression2> zur bedingten Auswahl verwendet hatte. Das Verhalten von Python diesbezüglich unterscheidet sich jedoch von dem einiger anderer Sprachen, und bei unvorsichtiger Verwendung kann es zu Fehlern führen!
Schauen Sie sich die folgenden beiden Beispiele an. Welche Ergebnisse erwarten Sie?
a = True and True or "Python" b = True and False or "Python"
Für <condition> and <expression1> or <expression2> wird bei falscher Bedingung direkt expression2 ausgewertet und zurückgegeben. Wenn die Bedingung wahr ist, wird expression1 ausgewertet; wenn expression1 ebenfalls wahr ist, wird expression2 nicht ausgewertet. Aber wenn expression1 nicht wahr ist, wird expression2 ausgewertet und zurückgegeben.
In den obigen Beispielen wird a also zu True ausgewertet, während b zu "Python" führt.
Python behandelt Wahrhaftigkeit auf besondere Weise. Zum Beispiel stieß der Autor dieser E-Mail auf eine Situation, in der expression1 eine komplexe Zahl 0+4i war, die in Bezug auf die Wahrhaftigkeit als False ausgewertet wird. Infolgedessen war die endgültige Rückgabe nicht die beabsichtigte expression1, sondern expression2!
Bevor eine bessere Lösung eingeführt wurde, war das and-or-Muster eine relativ gängige Methode zur bedingten Auswahl. PEP 308 erwähnte auch diesen Ansatz und wies darauf hin, dass expression1 zu Problemen führen könnte, wenn es als falsch ausgewertet wird. Es bezeichnete dieses Muster sogar als hässlich und verwirrend.
Diese E-Mail entzündete erneut die Diskussion in der Community über bedingte Syntax, und prominente Entwickler begannen, sich zu äußern.
Aus heutiger Sicht ist klar, dass die Entwickler mit dem Status quo von if-else unzufrieden waren. Der beliebte and-or-Workaround war jedoch nicht gut genug, so dass der Wunsch nach einer neuen, standardisierten Syntax zur Lösung dieses Problems groß war.
Ein einzigartiger bedingter Ausdruck
Nach 10 Tagen E-Mail-Diskussion entschied Guido van Rossum schließlich, einen bedingten Ausdruck mit der Syntax X if C else Y einzuführen. Infolgedessen wurde PEP 308 wieder geöffnet und aktualisiert, und die Funktion wurde im folgenden Jahr in Python 2.5 implementiert.
Dies ist die Syntax, die wir zuvor erwähnt haben und mit der einige Leute sich unwohl fühlten – weil die Bedingung nicht am Anfang steht.
Warum wurde dies zum siegreichen Design? War es die optimale Wahl?
Unbestreitbar war der entscheidende Faktor Guido selbst. Da im Community-Votum eineinhalb Jahre zuvor kein Mehrheitskonsens erzielt wurde, übte er seine Macht als BDFL (Benevolent Dictator For Life) aus, um die seiner Meinung nach beste Lösung zu wählen.
X if C else Y ist sehr leicht verständlich und gut lesbar. Es folgt Pythons Stil "explizit ist besser als implizit", indem es intuitive, natürlichsprachliche if-else-Konstrukte anstelle von potenziell verwirrender Zeichensetzung verwendet. Dies ähnelt der Verwendung von and und or anstelle von Symbolen wie && und || in Python.
Auch wenn die angepasste Reihenfolge dieser Syntax gewöhnungsbedürftig sein mag, hat die Implementierung erhebliche Vorteile. Erstens werden nur die vorhandenen Schlüsselwörter if und else wiederverwendet, ohne neue Schlüsselwörter wie then oder when oder zusätzliche Syntaxelemente einzuführen. Es ist auch weniger umständlich als das Format (if <condition>: <expression1> else: <expression2>).
Zweitens überprüfte Guido zur Verifizierung der Wirksamkeit von X if C else Y alle Verwendungen der and-or-Kombination in der Standardbibliothek und stellte fest, dass jede Instanz von C and X or Y durch X if C else Y ersetzt werden konnte. Der Zustand der Standardbibliothek bewies, dass die neue Syntax brauchbar war.
Rückblickend auf diese Geschichte können wir einen klaren roten Faden erkennen: Python hat den ?:-ternären Operator hauptsächlich nicht übernommen, weil er nicht mit dem Schwerpunkt der Sprache auf Klarheit und Geradlinigkeit übereinstimmt. Stattdessen führte es den X if C else Y-Ausdruck ein, um die Fallstricke des and-or-Musters zu eliminieren. Dieses Design ist prägnant, gut lesbar und sehr nützlich.
Insgesamt legen die Designer von Python großen Wert auf Lesbarkeit und Wartbarkeit. Die Entscheidung, den ternären Operator nicht zu übernehmen und stattdessen einen neuen bedingten Ausdruck zu entwickeln, war das Ergebnis offener Diskussionen, sorgfältiger Bewertung und ausgewogener Kompromisse.
Warum Go und Rust den ternären Operator nicht unterstützen?
Nachdem wir die Designentscheidungen von Python untersucht haben, werfen wir einen Blick auf zwei der beliebtesten Sprachen im "gegnerischen Lager".
Zuerst Go. Die offizielle FAQ von Go enthält eine spezielle Frage: "Warum hat Go den ?: Operator nicht?"
Go unterstützt den ?:-Operator nicht und empfiehlt stattdessen die native if-else-Syntax. Die Dokumentation liefert eine kurze Erklärung in nur einem Absatz:
Go hat keinen
?:-Operator, weil die Designer gesehen haben, dass er zur Erstellung verwirrender, komplexer Ausdrücke verwendet wurde. Obwohlif-elselänger ist, ist es zweifellos klarer. Eine Sprache braucht nur eine bedingte Kontrollflussstruktur.
Als nächstes Rust. Seine offizielle Dokumentation scheint nicht zu erklären, warum der ternäre Operator nicht unterstützt wird. Aber mit weiterer Recherche habe ich herausgefunden, dass er eine interessante Hintergrundgeschichte hat: Im Juni 2011 führte Rust tatsächlich den ternären Operator (#565) ein, aber innerhalb von sechs Monaten stellten die Designer fest, dass er redundant war und entfernten ihn (#1698, #4632)!
Warum wurde der ternäre Operator in Rust als redundant angesehen? Weil im Gegensatz zu vielen anderen Sprachen if in Rust kein Statement, sondern ein Expression ist. Das bedeutet, dass Sie das Ergebnis eines if-Ausdrucks direkt einer Variablen zuweisen können:
// Wenn die Bedingung wahr ist, erhält man 5, andernfalls 6 let number = if condition { 5 } else { 6 };
Diese Syntax ist einfach und klar – sie ist wie die Verwendung des vertrauten if-else zur Zuweisung. Sie durch einen ternären Operator zu ersetzen, wäre unnötig, ja sogar überflüssig.
Darüber hinaus verwendet Rust geschweifte Klammern zur Definition von Codeblöcken, sodass der Inhalt innerhalb der Klammern mehrere Ausdrücke enthalten und sogar Zeilenumbrüche unterstützen kann, wie im folgenden Beispiel:
let x = 42; let result = if x > 50 { println!("x ist größer als 50"); x * 2 // Dies ist ein Ausdruck, und sein Wert wird `result` zugewiesen } else { println!("x ist kleiner oder gleich 50"); x / 2 // Dies ist ebenfalls ein Ausdruck, der zurückgegeben und `result` zugewiesen wird };
Diese Art der Nutzung wäre in Python unmöglich. Der wichtigste Unterschied besteht darin, dass if in Rust ein Expression und kein Statement ist.
Der Unterschied zwischen den beiden Konzepten ist:
- Expression: Ein Codefragment, das aus Variablen, Konstanten, Operatoren usw. besteht, das zu einem Wert ausgewertet wird und innerhalb anderer Ausdrücke oder Anweisungen verwendet werden kann.
- Statement: Eine einzelne Anweisung oder eine Gruppe von Anweisungen, die eine Aktion ausführen, wie Zuweisungen, Bedingungen oder Schleifen. Statements geben keine Werte zurück (oder geben nichts zurück) und können nicht in Ausdrücken verwendet werden.
Neben Rust gibt es andere Programmiersprachen, in denen if eine Expression ist, wie Kotlin, Scala, F# und Swift. Theoretisch benötigen diese Sprachen ebenfalls keinen ternären Operator. (Nebenbemerkung: Swift ist eine Ausnahme – es hat einen ternären Operator. Kotlin hat ebenfalls einen ?:-Operator, aber beachte, dass die beiden Symbole verbunden sind. Zum Beispiel bedeutet val result = a ?: b: Wenn a nicht null ist, weise es result zu; andernfalls weise b zu.)
Aufgrund dieser sprachlichen Designunterschiede gehen Rust und Python/Go von grundlegend unterschiedlichen Ausgangspunkten an die Frage des ternären Operators heran. Sobald Sie diesen Unterschied verstanden haben, erhalten Sie eine klarere Perspektive auf Programmiersprachen.
Also, zurück zur ursprünglichen Frage: Warum übernehmen einige Programmiersprachen nicht die Mainstream-Syntax des ternären Operators?
Es ist unbestreitbar, dass ?: ein prägnantes und nützliches Design ist. Der Nachteil der Verwendung von Zeichensetzung ist jedoch, dass sie übermäßig abstrakt und weniger lesbar als If-Else sein kann. Darüber hinaus führen unterschiedliche Sprachphilosophien und Nutzungsgewohnheiten zu unterschiedlichen Entscheidungen.
Python traf nach vielen Wendungen schließlich seine eigene, einzigartige bedingte Ausdruckssyntax. Go erklärt ausdrücklich, dass es den ternären Operator nicht unterstützt. Rust führte ihn ein und entfernte ihn dann wieder – hauptsächlich aufgrund seiner grundlegenden Verwendung von if als Expression.
Wir sind Leapcell, Ihre Top-Wahl für das Hosting von Rust-Projekten.
Leapcell ist die Serverless-Plattform der nächsten Generation für Webhosting, asynchrone Aufgaben und Redis:
Multi-Sprachen-Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Unbegrenzte Projekte kostenlos bereitstellen
- Zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 $ unterstützen 6,94 Mio. Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollständig automatisierte CI/CD-Pipelines und GitOps-Integration.
- Echtzeit-Metriken und Protokollierung für handlungsorientierte Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Auto-Skalierung zur einfachen Bewältigung hoher Gleichzeitigkeit.
- Kein Betriebsaufwand – konzentrieren Sie sich einfach auf die Entwicklung.
Entdecken Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ



