Die allgemeine Antwort lautet, dass +=
versucht wird, die __iadd__
spezielle Methode aufzurufen , und wenn diese nicht verfügbar ist, wird versucht, sie zu verwenden__add__
stattdessen . Das Problem ist also der Unterschied zwischen diesen speziellen Methoden.
Die __iadd__
spezielle Methode ist für eine In-Place-Addition vorgesehen, dh sie mutiert das Objekt, auf das sie einwirkt. Die __add__
spezielle Methode gibt ein neues Objekt zurück und wird auch für den Standardoperator verwendet +
.
Wenn der +=
Operator für ein Objekt verwendet wird, für das eine __iadd__
Definition vorliegt, wird das Objekt an Ort und Stelle geändert. Andernfalls wird stattdessen versucht, die Ebene zu verwenden __add__
und ein neues Objekt zurückzugeben.
Aus diesem Grund +=
ändert für veränderbare Typen wie Listen der Wert des Objekts, während für unveränderliche Typen wie Tupel, Zeichenfolgen und Ganzzahlen stattdessen ein neues Objekt zurückgegeben wird ( a += b
entsprichta = a + b
).
Für die Typen , dass die Unterstützung sowohl __iadd__
und __add__
Sie deshalb sein müssen aufpassen , welche Sie verwenden. a += b
ruft auf __iadd__
und mutiert a
, während a = a + b
ein neues Objekt erstellt und zugewiesen wird a
. Sie sind nicht die gleiche Operation!
>>> a1 = a2 = [1, 2]
>>> b1 = b2 = [1, 2]
>>> a1 += [3] # Uses __iadd__, modifies a1 in-place
>>> b1 = b1 + [3] # Uses __add__, creates new list, assigns it to b1
>>> a2
[1, 2, 3] # a1 and a2 are still the same list
>>> b2
[1, 2] # whereas only b1 was changed
Für unveränderliche Typen (wo Sie keine haben __iadd__
) a += b
und a = a + b
gleichwertig sind. Dies ist es, was Sie +=
für unveränderliche Typen verwenden können, was eine seltsame Entwurfsentscheidung sein könnte, bis Sie bedenken, dass Sie es sonst nicht +=
für unveränderliche Typen wie Zahlen verwenden könnten !