Die "erweiterten" Zuweisungsoperatoren wie +=
wurden in Python 2.0 eingeführt, das im Oktober 2000 veröffentlicht wurde. Das Design und die Begründung sind in PEP 203 beschrieben . Eines der erklärten Ziele dieser Betreiber war die Unterstützung des Vor-Ort-Betriebs. Schreiben
a = [1, 2, 3]
a += [4, 5, 6]
soll die Liste a
an Ort und Stelle aktualisieren . Dies ist wichtig, wenn andere Verweise auf die Liste vorhanden sind a
, z. B. wann a
als Funktionsargument empfangen wurde.
Die Operation kann jedoch nicht immer an Ort und Stelle ausgeführt werden, da viele Python-Typen, einschließlich Ganzzahlen und Zeichenfolgen, unveränderlich sind , sodass z. B. i += 1
eine Ganzzahl i
möglicherweise nicht an Ort und Stelle ausgeführt werden kann.
Zusammenfassend sollte gesagt werden, dass erweiterte Zuweisungsoperatoren nach Möglichkeit an Ort und Stelle arbeiten und ansonsten ein neues Objekt erstellen sollten. Um diese Entwurfsziele zu vereinfachen, wurde der Ausdruck x += y
so angegeben, dass er sich wie folgt verhält:
- Wenn
x.__iadd__
definiert, x.__iadd__(y)
wird ausgewertet.
- Andernfalls wird, wenn
x.__add__
implementiert, x.__add__(y)
ausgewertet.
- Andernfalls wird, wenn
y.__radd__
implementiert, y.__radd__(x)
ausgewertet.
- Andernfalls wird ein Fehler ausgelöst.
Das erste Ergebnis, das durch diesen Prozess erhalten wird, wird zurück zugewiesen x
(es sei denn, dieses Ergebnis ist der NotImplemented
Singleton. In diesem Fall wird die Suche mit dem nächsten Schritt fortgesetzt).
Dieser Prozess ermöglicht die Implementierung von Typen, die direkte Änderungen unterstützen __iadd__()
. Typen, die keine direkte Änderung unterstützen, müssen keine neuen magischen Methoden hinzufügen, da Python automatisch auf im Wesentlichen zurückgreift x = x + y
.
Kommen wir nun zu Ihrer eigentlichen Frage: Warum können Sie einer Liste mit einem erweiterten Zuweisungsoperator ein Tupel hinzufügen? Aus dem Speicher war der Verlauf ungefähr so: Die list.__iadd__()
Methode wurde implementiert, um einfach die bereits vorhandene list.extend()
Methode in Python 2.0 aufzurufen . Bei der Einführung von Iteratoren in Python 2.1 wurde die list.extend()
Methode aktualisiert, um beliebige Iteratoren zu akzeptieren. Das Endergebnis dieser Änderungen war, dass my_list += my_tuple
ab Python 2.1 funktioniert wurde. Die list.__add__()
Methode sollte jedoch niemals beliebige Iteratoren als rechtes Argument unterstützen - dies wurde für eine stark typisierte Sprache als unangemessen angesehen.
Ich persönlich denke, dass die Implementierung erweiterter Operatoren in Python etwas zu komplex war. Es hat viele überraschende Nebenwirkungen, zB dieser Code:
t = ([42], [43])
t[0] += [44]
Die zweite Zeile erhöht TypeError: 'tuple' object does not support item assignment
, aber die Operation erfolgreich ohnehin durchgeführt - t
wird ([42, 44], [43])
nach der Zeile ausgeführt werden, die den Fehler auslöst.