Les opérateurs d'affectation "augmentés" comme +=
ont été introduits dans Python 2.0, qui a été publié en octobre 2000. La conception et la justification sont décrites dans PEP 203 . L'un des objectifs déclarés de ces opérateurs était de soutenir les opérations sur place. L'écriture
a = [1, 2, 3]
a += [4, 5, 6]
est censé mettre à jour la liste a
en place . Cela est important s'il existe d'autres références à la liste a
, par exemple quand a a
été reçu comme argument de fonction.
Cependant, l'opération ne peut pas toujours se produire sur place, car de nombreux types Python, y compris les entiers et les chaînes, sont immuables , par exemple i += 1
pour un entier i
ne peut pas fonctionner sur place.
En résumé, les opérateurs d'affectation augmentée étaient censés fonctionner sur place lorsque cela était possible et créer un nouvel objet dans le cas contraire. Pour faciliter ces objectifs de conception, l'expression a x += y
été spécifiée pour se comporter comme suit:
- Si
x.__iadd__
est défini, x.__iadd__(y)
est évalué.
- Sinon, if
x.__add__
est implémenté x.__add__(y)
est évalué.
- Sinon, if
y.__radd__
est implémenté y.__radd__(x)
est évalué.
- Sinon, déclenchez une erreur.
Le premier résultat obtenu par ce processus sera affecté à nouveau x
(sauf si ce résultat est le NotImplemented
singleton, auquel cas la recherche se poursuit à l'étape suivante).
Ce processus permet aux types qui prennent en charge la modification sur place à implémenter __iadd__()
. Les types qui ne prennent pas en charge la modification sur place n'ont pas besoin d'ajouter de nouvelles méthodes magiques, car Python reviendra automatiquement à essentiellement x = x + y
.
Venons-en enfin à votre question réelle - pourquoi vous pouvez ajouter un tuple à une liste avec un opérateur d'affectation augmenté. De mémoire, l'historique de ceci était à peu près comme ceci: La list.__iadd__()
méthode a été implémentée pour appeler simplement la list.extend()
méthode déjà existante dans Python 2.0. Lorsque les itérateurs ont été introduits dans Python 2.1, la list.extend()
méthode a été mise à jour pour accepter les itérateurs arbitraires. Le résultat final de ces changements a my_list += my_tuple
fonctionné à partir de Python 2.1. La list.__add__()
méthode, cependant, n'a jamais été censé soutenir itérateurs arbitraires comme argument de droite - cela a été jugé inapproprié pour un langage fortement typé.
Personnellement, je pense que l'implémentation des opérateurs augmentés a fini par être un peu trop complexe en Python. Il a de nombreux effets secondaires surprenants, par exemple ce code:
t = ([42], [43])
t[0] += [44]
La deuxième ligne soulève TypeError: 'tuple' object does not support item assignment
, mais l'opération est réalisée avec succès de toute façon - t
sera ([42, 44], [43])
après l' exécution de la ligne qui soulève l'erreur.