Trying to understand += better

Steve Howell showell30 at yahoo.com
Sun Nov 22 23:01:46 EST 2009


On Nov 22, 7:28 pm, Lie Ryan <lie.1... at gmail.com> wrote:
> Roy Smith wrote:
> > If I've got an object foo, and I execute:
>
> > foo.bar += baz
>
> > exactly what happens if foo does not have a 'bar' attribute?  It's
> > pretty clear that foo.__getattr__('bar') gets called first, but it's a
> > little murky after that.  Assume for the moment that foo.__getattr__
> > ('bar') returns an object x.  I think the complete sequence of calls
> > is:
>
> > foo.__getattr__('bar')  ==> x
> > x.__add__(baz)  ==> y
> > foo.__setattr__('bar', y)
>
> > but I'm not 100% sure.  It would be nice if it was, because that would
> > let me do some very neat magic in a system I'm working on :-)
>
> > How would things change if X defined __iadd__()?
>
> The semantic of the in-place operator is something like:
> x += y
> becomes
> x = x.__iadd__(y)
>
> thus
> foo.bar += baz
> becomes
> foo.bar = foo.bar.__iadd__(baz)
>
> So the call sequence is,
> foo.__getattr__('bar') ==> x
> x.__iadd__(baz) ==> y
> foo.__setattr__('bar', y)
>
> the default definition of object.__iadd__ is something like this:
> def __iadd__(self, other):
>      # this calls self.__add__ or other.__radd__ according to the
>      # operator call rule, may call __coerce__ or any other magics
>      # in operator calling
>      return self + other

The __iadd__ method will often return self for mutable types.  So, for
example, these two statements are NOT identical where lst is a list:

lst = lst + [3]
lst += [3]

The first statement is creating a whole new list; the second one
isn't.


http://docs.python.org/reference/datamodel.html



More information about the Python-list mailing list