Gli operatori di assegnazione "aumentati" come +=sono stati introdotti in Python 2.0, che è stato rilasciato nell'ottobre 2000. Il design e la logica sono descritti in PEP 203 . Uno degli obiettivi dichiarati di questi operatori era il supporto delle operazioni sul posto. scrittura
a = [1, 2, 3]
a += [4, 5, 6]
dovrebbe aggiornare l'elenco a in atto . Questo importa se ci sono altri riferimenti all'elenco a, ad esempio quando è astato ricevuto come argomento di funzione.
Tuttavia, l'operazione non può sempre avvenire sul posto, poiché molti tipi di Python, inclusi numeri interi e stringhe, sono immutabili , quindi ad es. i += 1Per un numero intero inon è possibile operare sul posto.
In sintesi, gli operatori di assegnazione aumentata dovevano lavorare sul posto quando possibile e creare un nuovo oggetto in caso contrario. Per facilitare questi obiettivi di progettazione, l'espressione è x += ystata specificata per comportarsi come segue:
- Se
x.__iadd__definito, x.__iadd__(y)viene valutato.
- Altrimenti, se
x.__add__viene implementato x.__add__(y)viene valutato.
- Altrimenti, se
y.__radd__viene implementato y.__radd__(x)viene valutato.
- Altrimenti solleva un errore.
Il primo risultato ottenuto da questo processo verrà assegnato nuovamente x(a meno che quel risultato non sia il NotImplementedsingleton, nel qual caso la ricerca continua con il passaggio successivo).
Questo processo consente l'implementazione di tipi che supportano la modifica sul posto __iadd__(). I tipi che non supportano la modifica sul posto non hanno bisogno di aggiungere nuovi metodi magici, poiché Python tornerà automaticamente a essenzialmente x = x + y.
Quindi, veniamo finalmente alla tua vera domanda: perché puoi aggiungere una tupla a un elenco con un operatore di assegnazione aumentato. Dalla memoria, la storia di questo è stata più o meno così: il list.__iadd__()metodo è stato implementato per chiamare semplicemente il list.extend()metodo già esistente in Python 2.0. Quando gli iteratori sono stati introdotti in Python 2.1, il list.extend()metodo è stato aggiornato per accettare iteratori arbitrari. Il risultato finale di queste modifiche è stato che ha my_list += my_tuplefunzionato a partire da Python 2.1. Il list.__add__()metodo, tuttavia, non avrebbe mai dovuto supportare iteratori arbitrari come argomento di destra - questo era considerato inappropriato per un linguaggio fortemente tipizzato.
Personalmente penso che l'implementazione di operatori aumentati sia stata un po 'troppo complessa in Python. Ha molti effetti collaterali sorprendenti, ad esempio questo codice:
t = ([42], [43])
t[0] += [44]
La seconda riga viene sollevata TypeError: 'tuple' object does not support item assignment, ma l'operazione viene comunque eseguita correttamente : tsarà ([42, 44], [43])dopo aver eseguito la riga che genera l'errore.