Die Python-Sprache (insbesondere 3.x) ermöglicht das sehr allgemeine Entpacken von Iterables, ein einfaches Beispiel dafür
a, *rest = 1, 2, 3
Im Laufe der Jahre wurde dieses Auspacken schrittweise verallgemeinert (siehe z. B. PEP 3132 und PEP 448 ), so dass es unter immer mehr Umständen verwendet werden kann. Daher war ich überrascht zu entdecken, dass die folgende Syntax in Python 3.6 ungültig ist (und dies auch in Python 3.7 bleibt):
def f():
rest = [2, 3]
return 1, *rest # Invalid
Ich kann es zum Laufen bringen, indem ich das zurückgegebene Tupel wie folgt in Klammern kapsle:
def f():
rest = [2, 3]
return (1, *rest) # Valid
Die Tatsache, dass ich dies in einer return
Aussage verwende, scheint wichtig zu sein
t = 1, *rest
ist in der Tat legal und führt zum gleichen mit und ohne Klammern.
Wurde dieser Fall von den Python-Entwicklern einfach vergessen, oder gibt es einen Grund, warum dieser Fall eine ungültige Syntax ist?
Warum es mich interessiert
Dies bricht einen wichtigen Vertrag, den ich mit der Python-Sprache zu haben glaubte. Betrachten Sie die folgende (auch gültige) Lösung:
def f():
rest = [2, 3]
t = 1, *rest
return t
Wenn ich Code wie diesen habe, halte ich ihn normalerweise t
für einen temporären Namen, den ich loswerden sollte, indem ich ihn einfach t
in der unteren Zeile durch seine Definition ersetze . In diesem Fall führt dies jedoch zu einem ungültigen Code
def f():
rest = [2, 3]
return 1, *rest
Es ist natürlich keine große Sache, Klammern um den Rückgabewert setzen zu müssen, aber normalerweise werden zusätzliche Klammern nur benötigt, um zwischen mehreren möglichen Ergebnissen zu unterscheiden (Gruppierung). Hier ist dies nicht der Fall, da das Weglassen der Klammern kein anderes unerwünschtes Verhalten hervorruft, sondern überhaupt kein Verhalten.
Aktualisieren
Seit Python 3.8 (siehe Punkt 7 in dieser Liste ) ist die oben beschriebene verallgemeinerte Syntax jetzt gültig.