inconsistency with += between different types ?

Huaiyu Zhu huaiyu at gauss.almadan.ibm.com
Tue Aug 6 21:16:07 CEST 2002


Andreas Leitgeb <Andreas.Leitgeb at siemens.at> wrote:
>Huaiyu Zhu <huaiyu at gauss.almadan.ibm.com> wrote:
>> That's what it should be.  Yet it is possible for whoever writes __iadd__ to
>> define it the other way.  
>Really ?
>
>Inside __iadd__ I've got the "self"-parameter:
> If I assign directly to "self", then it won't have any effect outside 
>   the method.
> If I assign to self.whatever, I mutate the object in place.
>Is there something I've missed, or does it indeed boil down to 
> defining or not defining __ixxx__ ?

The thing missing is that the return statement plays an unnecessarily big
role here.  See below.

>Also, what characterizes an object to be mutable ?
>Is it the existence or not-existence of mutating methods, or
> is the more behind the scenes of strings,ints and tuples ?

No concept of mutability is invoked in this case, apart from the behavior of
__iadd__, or lack of it.

>> Consider this table:
>>                 in place         assignment
>>             +---------------+----------------+
>> mutable     |       A       |        B       |
>>             +---------------+----------------+
>> immutable   |       C       |        D       |
>>             +---------------+----------------+
>How I understand it:  (and it looks quite reasonable that way)
>(__iadd__ stands for all the __i...__-methods)
>A: __iadd__ is defined
>B: only __add__ is defined, not __iadd__
>C: hmm, if __iadd__ is defined, then "per definition" the object
>     is not immutable, thus not C :-)
>D: neither __iadd__ nor any other mutating method is defined,
>     but __add__ is.

Not quite right.  You can get B or D even if you define __iadd__, by
returning an object other than self.

By the way, if you forget to return self, you rebind the name to None.

>>> class A:
...    def __iadd__(self,x): print x
... 
>>> a = A()
>>> a+=3
3
>>> print a
None

The operator += would be much easier to understand had the design be such
that B and D are only supported if __iadd__ is not defined.  That would
eliminate the ability to use += with assignment semantics that is different
from x=x+y.  I doubt such usage is of any importance anyway.


Huaiyu



More information about the Python-list mailing list