inconsistency with += between different types ?

Andreas Leitgeb Andreas.Leitgeb at
Thu Aug 8 13:34:47 CEST 2002

Donn Cave <donn at> wrote:
> class Currency:
>     ...
>     def __iadd__(self, v):
>         return self + v
>     def __add__(self, v):
>         ...
> d=Currency(...)
> c=d
> d+=2; # does not change c

While being effectively correct, this code-snippet kind of demonstrates, 
 that you, too, have a wrong understanding of how  += leads to calling 
 __iadd__ or __and__.

Note: You don't need to define __iadd__ to be able to do a += .
In your example, you could just remove your definition 
of __iadd__, as it yields nothing, but costs a little performance
and adds complexity.

In your example, "d+=2" causes "d.__iadd(...)__" to be called, 
 which then calls (through "+") d.__add(...)__. In the end, the result
 is re-assigned to d, making d point to a new object (as you intended,
 but as you could have done easier)
Without __iadd__ in your class,  "d+=2" would detect that there is no 
 __iadd__, and as a consequence call __add__ instead, and then re-assign 
 the new object (returned by __add__) to d.  
 One actual call saved. One possible niche for bugs diminished.

My suggestion would push python-programmers into understanding what 
 __iadd__ is really good for and what it is not necessary for.

This thread got started, because I had failed to remember the 
  concept of immutable built-in types - my fault, because it was
  clearly described even in my small book.
Now, I'm glad that this happened, because I've learnt from the answers, 
  that __iadd__ works quite different from what I'd have called intuitive. 
  (and this, the book omitted to explain, likely for brevity's sake)

Because += already has this fallback to __add__ builtin, __iadd__ 
  shouldn't care about the immutable case. It need not even exist for 
  that case.   Now for the mutable case, it should be __iadd__'s only
  job to get the mutation done on the object.

Because there might be code out there, like the one you wrote, which
  wouldn't work afterwards (as the __add__ is hidden by a non-mutating
  __iadd__), I added, that there would have to be warnings issued for
  helping transition of wrongly designed code.

Newsflash: Sproingy made it to the ground !
  read more ... <>

More information about the Python-list mailing list