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

Beim Programmieren müssen wir oft bedingte Urteile fällen und je nach Ergebnis unterschiedliche Codeblöcke ausführen. In vielen Programmiersprachen ist der bedingte Operator die gebräuchlichste Methode dafür. Python unterstützt den bedingten Operator jedoch nicht. Interessanterweise unterstützen auch zwei der beliebtesten aufstrebenden Sprachen, Go und Rust, ihn nicht!
Warum unterstützt Python den bedingten Operator nicht? Dieser Artikel analysiert hauptsächlich den Prozess hinter dem Entwurf der bedingten Syntax von Python und erklärt, warum es eine einzigartige Implementierung gewählt hat. Gleichzeitig werden wir untersuchen, warum auch andere Sprachen den traditionellen bedingten Operator aufgegeben haben.
Was ist der bedingte Operator?
Der bedingte Operator bezieht sich im Allgemeinen auf ?:
mit einer Syntax in der Form: Bedingung ? Ausdruck1 : Ausdruck2
. Wenn die Bedingung wahr ist, wird Ausdruck1
ausgewertet; andernfalls wird Ausdruck2
ausgewertet.
Die vereinfachte Form a ? b : c
kann gelesen werden als "wenn die Bedingung a
wahr ist, gib b
zurück, andernfalls gib c
zurück."
Der bedingte Operator ist eine vereinfachte Version einer Standard-if-else-Struktur und wird häufig verwendet, um bedingte Prüfungen durchzuführen und Werte in einer einzigen Anweisung zurückzugeben.
// Reguläres 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 damit vertraut gemacht hat), was sie sehr beliebt macht.
Es gibt jedoch auch Nachteile. Python ist der bekannteste Herausforderer dieses Designansatzes. Lassen Sie uns untersuchen, warum Python einen anderen Weg gewählt hat.
Die Abstimmung der Python-Community
Python wurde 1991 veröffentlicht, aber in den nächsten 15 Jahren hatte es nur eine if-else-Syntax für Bedingungen und unterstützte keine bedingten Operatoren oder andere bedingte Ausdrücke. Bevor 2006 bedingte Ausdrücke eingeführt wurden, führte die Community eine lange und komplizierte Debatte – man kann sagen, dass dies ein schwieriges Syntaxmerkmal war, um es zu finalisieren.
Ursprünglich wurde aufgrund wiederholter Anfragen, einen if-then-else-Ausdruck (ternär) hinzuzufügen, PEP 308 – Bedingte Ausdrücke im Februar 2003 vorgeschlagen. Ziel war es, eine Lösung auszuwählen, die die Mehrheit der Community unterstützen konnte.
Bald entstanden innerhalb der Community mehrere Vorschläge, abgesehen von einer kleinen Gruppe, die es vorzog, nichts zu tun:
(1) Punktuationsbasierter bedingter Operator
Dies ist der konventionelle bedingte Operator, der dieselbe Syntax wie zuvor verwendet:
<Bedingung> ? <Ausdruck1> : <Ausdruck2>
Dieser Vorschlag war sehr beliebt, und einige Entwickler reichten sogar Implementierungscode ein. Guido lehnte ihn jedoch aus zwei Gründen ab: Der Doppelpunkt hatte bereits viele Verwendungszwecke in Python (obwohl Mehrdeutigkeit unwahrscheinlich war, da das Fragezeichen einen passenden Doppelpunkt erfordern würde); 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 Schlüsselworts then
und Kombination mit dem vorhandenen else
:
<Bedingung> then <Ausdruck1> else <Ausdruck2>
Zu seinen Vorteilen gehörten Klarheit, keine Notwendigkeit für Klammern, keine Änderung der Semantik vorhandener Schlüsselwörter, geringes Risiko, mit einer Anweisung verwechselt zu werden, und keine Überlastung des Doppelpunkts. Der Nachteil war, dass das Hinzufügen eines neuen Schlüsselworts in Bezug auf die Implementierung kostspielig wäre.
(3) Andere Vorschläge
Diese waren im Wesentlichen ähnlich wie der zweite Ansatz, fanden aber nicht so viel Unterstützung:
(if <Bedingung>: <Ausdruck1> else: <Ausdruck2>) <Bedingung> and <Ausdruck1> else <Ausdruck2> <Ausdruck1> if <Bedingung> else <Ausdruck2> cond(<Bedingung>, <Ausdruck1>, <Ausdruck2>)
Bemerkenswert ist, dass das Format (if <Bedingung>: <Ausdruck1> else: <Ausdruck2>)
eine vereinfachte Version der regulären if-else-Syntax ist, die leicht zu verstehen ist, aber Klammern erfordert. Dies kann zu Verwechslungen mit Generatorausdrücken führen und erfordert eine spezielle Behandlung des Doppelpunkts durch den Interpreter.
Ebenfalls erwähnenswert ist <Ausdruck1> if <Bedingung> else <Ausdruck2>
, was der ursprünglich empfohlene Vorschlag in frühen Versionen von PEP 308 war. Einige Leute mochten diese Form jedoch nicht, weil sie die Bedingung nicht an den Anfang stellte. Wenn Ausdruck1
lang ist, ist es außerdem leicht, die Bedingung ganz zu übersehen.
Hier waren alle Optionen, über die zu dieser Zeit abgestimmt wurde:
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. any write-in vote
Im Allgemeinen wollten die Entwickler eine Form von if-then-else-Ausdruck einführen, aber nach der Abstimmung erhielt keine Option eine klare Mehrheit. Die Streitigkeiten liefen darauf hinaus: ob Punktuierung verwendet werden soll, Schlüsselwörter wiederverwendet werden sollen, Klammern wiederverwendet werden sollen, neue Schlüsselwörter eingeführt werden sollen oder neue Syntax hinzugefügt werden soll...
Da die Stimmen zu fragmentiert waren, wurde das PEP zu diesem Zeitpunkt abgelehnt. Das PEP besagte: "Eines der Designprinzipien von Python ist es, angesichts der Unsicherheit den Status quo aufrechtzuerhalten."
Probleme bei der Verwendung von and-or
zur bedingten Auswahl
Die oben genannte Abstimmung fand im März 2004 statt, aber die Diskussionen zu diesem Thema ebbten nach der Ablehnung von PEP 308 nicht ab. Die Entwickler suchten immer noch nach einer prägnanten Möglichkeit, if-else
zu ersetzen.
Im September 2005 schlug jemand auf der Mailingliste vor, die Logik der Operatoren and
und or
in Python 3.0 zu ändern. Die Idee war, and
und or
zu vereinfachen, sodass sie immer boolesche Werte zurückgeben, anstatt den zuletzt ausgewerteten Operanden zurückzugeben.
Der Grund für diesen Vorschlag war, dass der Autor die Form <Bedingung> and <Ausdruck1> or <Ausdruck2>
verwendet hatte, um eine bedingte Auswahl durchzuführen. Das Verhalten von Python unterscheidet sich jedoch in dieser Hinsicht von einigen anderen Sprachen, und wenn es unachtsam verwendet wird, kann es zu Fehlern führen!
Schauen Sie sich die folgenden zwei Beispiele an. Welche Ergebnisse würden Sie erwarten?
a = True and True or "Python" b = True and False or "Python"
Für <Bedingung> and <Ausdruck1> or <Ausdruck2>
wird, wenn die Bedingung falsch ist, direkt Ausdruck2
ausgewertet und zurückgegeben. Wenn die Bedingung wahr ist, wird Ausdruck1
ausgewertet; wenn Ausdruck1
ebenfalls wahr ist, wird Ausdruck2
nicht ausgewertet. Wenn Ausdruck1
jedoch nicht wahr ist, wird Ausdruck2
ausgewertet und zurückgegeben.
In den obigen Beispielen ergibt a
also True
, während b
zu `