inconsistency with += between different types ?
Jonathan Hogg
jonathan at onegoodidea.com
Tue Aug 6 13:13:19 EDT 2002
On 6/8/2002 17:16, in article
slrnakvugv.c05.Andreas.Leitgeb at pc7499.gud.siemens.at, "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 returned value from __iadd__ is assigned to the LHS.
>>> class Foo:
... def __iadd__( self, other ):
... print self, other
... return 'foo'
...
>>> x = Foo()
>>> x
<__main__.Foo instance at 0x416350>
>>> x += 5
<__main__.Foo instance at 0x416350> 5
>>> x
'foo'
>>>
Therefore, depending on the way you implement __iadd__ you will get either
re-assignment or mutating (or a horrific combination of the two).
> 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 ?
The main thing that characterises a mutable object is whether it can be
mutated ;-)
In general, immutability is used to guarantee certain behaviours. For
example, mutable integers don't really make a whole lot of sense anyway and
making integer objects immutable means they can be shared (all 5s are
references to the same 5 -- see the Flyweight Design Pattern).
But when you don't need to guarantee such behaviour you don't need to worry
particularly about mutability. Most objects in Python are mutable.
>> 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.
You can write your own immutable objects (well, mostly) that define
__iadd__. As noted above, you just return a new object, but you will get
this behaviour for free if you just define __add__.
>> Consequently we are seeing frequent questions on this issue.
> If it actually works the way, I now think it does, then it's just
> a lack of clear documentation.
Probably ;-)
Jonathan
More information about the Python-list
mailing list