Zależy to całkowicie od obiektu i.
+=wywołuje __iadd__metodę (jeśli istnieje - wycofuje się, __add__jeśli nie istnieje), podczas gdy +wywołuje __add__metodę 1 lub __radd__metodę w kilku przypadkach 2 .
Z perspektywy API, __iadd__ma być używany do modyfikowania obiektów podlegających mutacji w miejscu (zwracanie zmutowanego obiektu), podczas gdy __add__powinien zwracać nową instancję czegoś. W przypadku obiektów niezmiennych obie metody zwracają nową instancję, ale __iadd__umieszczą nową instancję w bieżącej przestrzeni nazw o tej samej nazwie, co stara instancja. Dlatego
i = 1
i += 1
wydaje się zwiększać i. W rzeczywistości dostajesz nową liczbę całkowitą i przypisujesz ją „na wierzchu” i- tracąc jedno odniesienie do starej liczby całkowitej. W tym przypadku i += 1jest dokładnie taki sam jak i = i + 1. Ale w przypadku większości zmiennych obiektów jest to inna historia:
Jako konkretny przykład:
a = [1, 2, 3]
b = a
b += [1, 2, 3]
print a #[1, 2, 3, 1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]
w porównaniu do:
a = [1, 2, 3]
b = a
b = b + [1, 2, 3]
print a #[1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]
Zauważ, jak w pierwszym przykładzie, ponieważ bi aodwoływać się do tego samego obiektu, kiedy używam +=na b, to faktycznie zmienia b(i awidzi, że zmiany też - Po tym wszystkim, to odwołuje się do tej samej listy). Jednak w drugim przypadku, gdy to zrobię b = b + [1, 2, 3], pobiera listę, która bsię do niej odwołuje, i łączy ją z nową listą [1, 2, 3]. Następnie przechowuje skonkatenowaną listę w bieżącej przestrzeni nazw jako b- Bez względu na bpoprzednią linię.
1 W wyrażeniu x + y, jeśli x.__add__nie jest realizowany lub jeśli x.__add__(y)powróci NotImplemented i xi ymają różne rodzaje , a następnie x + ystara się rozmowy y.__radd__(x). Tak więc w przypadku, gdy masz
foo_instance += bar_instance
jeśli Foosię nie implementuje __add__lub __iadd__wynik tutaj jest taki sam jak
foo_instance = bar_instance.__radd__(bar_instance, foo_instance)
2 W wyrażeniu foo_instance + bar_instance, bar_instance.__radd__będzie próbował wcześniej foo_instance.__add__ czy typ bar_instancejest podklasą typu foo_instance(na przykład issubclass(Bar, Foo)). Racjonalne jest to, bo Barjest w pewnym sensie „wyższy poziom” obiekt niż Footak Barpowinny uzyskać możliwość nadrzędnymi Foo„s zachowanie.
+=zachowuje się jakextend()w przypadku list.