Hacker News new | ask | show | jobs
by ben-schaaf 3849 days ago
The assignment aspect of __iadd__ is done like any other assignment in python. The one to one equivalent of eliteraspberrie's would be:

  class Vector2D:
      def __iadd__(self, other)
          return self + other
No "self mutation" as you suggest. a += b is equivalent to a = a.__iadd__(b)
1 comments

> No "self mutation" as you suggest.

Your example would be the implementation for immutable Vector2Ds, and is implemented for you if you just wrote __add__. (I presume object.__iadd__ falls back to self.__add__.)

The only time you should actually override __iadd__ is for mutable objects, in which case it should look more like

  class Vector2D:
      def __iadd__(self, other)
          for i, x in enumerate(other):
              self[i] += x
          return self
That's the self mutation I was talking about.

Well, strictly that's not OK either, since operators shouldn't be duck-typed. Instead you should do

  class Vector2D:
      def __iadd__(self, other)
          if not isinstance(other, Vector2D):
              return NotImplemented

          for i, x in enumerate(other):
              self[i] += x
          return self
> The only time you should actually override __iadd__ is for mutable objects

What would the rationale be for such a rule?

the docs don't mention anything like that https://docs.python.org/2/library/operator.html and I've never heard it before. In Python, neither integers nor strings are mutable and both support the "x += y" syntax.

The __iadd__ method works the same for both mutable and immutable objects AFAIK

> What would the rationale be for such a rule?

Because __iadd__ automatically delegates to __add__. For immutable objects that's the best you can do, so there's no reason to write both.