Questo dipende interamente dall'oggetto i.
+=chiama il __iadd__metodo (se esiste - riconnettendosi __add__se non esiste) mentre +chiama il __add__metodo 1 o il __radd__metodo in alcuni casi 2 .
Dal punto di vista dell'API, __iadd__dovrebbe essere usato per modificare gli oggetti mutabili sul posto (restituendo l'oggetto che è stato mutato) mentre __add__dovrebbe restituire una nuova istanza di qualcosa. Per oggetti immutabili , entrambi i metodi restituiscono una nuova istanza, ma __iadd__inseriranno la nuova istanza nello spazio dei nomi corrente con lo stesso nome della vecchia istanza. Ecco perché
i = 1
i += 1
sembra aumentare i. In realtà, ottieni un nuovo numero intero e lo assegni "sopra" i- perdendo un riferimento al vecchio numero intero. In questo caso, i += 1è esattamente lo stesso di i = i + 1. Ma, con la maggior parte degli oggetti mutabili, è una storia diversa:
A titolo di esempio concreto:
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]
rispetto a:
a = [1, 2, 3]
b = a
b = b + [1, 2, 3]
print a #[1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]
nota come nel primo esempio, dato che be ariferimento allo stesso oggetto, quando lo uso +=su b, in realtà cambia b(e avede anche quel cambiamento - Dopotutto, fa riferimento allo stesso elenco). Nel secondo caso, tuttavia, quando lo faccio b = b + [1, 2, 3], prende l'elenco che bfa riferimento e lo concatena con un nuovo elenco [1, 2, 3]. Quindi memorizza l'elenco concatenato nello spazio dei nomi corrente come b- Senza riguardo a quella che bera la linea prima.
1 Nell'espressione x + y, se x.__add__non è attuato o se x.__add__(y)i rendimenti NotImplemented e xed yhanno tipi diversi , quindi x + ytenta di chiamare y.__radd__(x). Quindi, nel caso in cui tu abbia
foo_instance += bar_instance
se Foonon implementa __add__o __iadd__quindi il risultato qui è lo stesso di
foo_instance = bar_instance.__radd__(bar_instance, foo_instance)
2 Nell'espressione foo_instance + bar_instance, bar_instance.__radd__verrà provato prima foo_instance.__add__ se il tipo di bar_instanceè una sottoclasse del tipo di foo_instance(ad es issubclass(Bar, Foo).). Il razionale di questo è perché Barè in un certo senso un oggetto "di livello superiore" rispetto Foocosì Bardovrebbe ottenere la possibilità di sovrascrivere Foo's comportamento.
+=si comporta comeextend()in caso di liste.