On Nov 22, 7:28 pm, Lie Ryan <lie.1...@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 -- http://mail.python.org/mailman/listinfo/python-list