Behavior of += (was Re: [Python-Dev] Customization docs)
Bengt Richter
bokr at oz.net
Wed Jun 5 19:39:12 EDT 2002
On Tue, 4 Jun 2002 08:03:30 -0400, "John Roth" <johnroth at ameritech.net> wrote:
>
>"Huaiyu Zhu" <huaiyu at gauss.almadan.ibm.com> wrote in message
>news:slrnafo7qv.37c.huaiyu at gauss.almadan.ibm.com...
>> Gustavo Cordova <gcordova at hebmex.com> wrote:
>
>>
>> Great explanation! The problem stems from the fact that the current
>+=
>> operator implements two semantically distinct operations, chosen
>according
>> to some properties of the operands. This is not unlike the situation
>of the
>> division operator with distinct behaviors on floats and ints.
>
>This is not an issue with '+='. It's an issue with assignment,
>regardless
>of whether it is standalone or combined with some other operation.
>
>And I disagree that assignment implements two distinct operations.
>Assignment always rebinds. Always. In the examples cited, it
Not so fast with that "Always." ;-)
>>> class P(object):
... def __init__(self,v): self._v = v
... def get_v(self): return self._v
... def set_v(self,v): return # ;-)
... v = property(get_v, set_v)
...
>>> p=P('orig value')
>>> p.v
'orig value'
>>> id(p.v)
8209984
>>> p.v = 'try a change'
>>> id(p.v)
8209984
>>> p.v
'orig value'
>>> p.v += ' try an increment'
>>> id(p.v)
8209984
>>> p.v
'orig value'
>attempted to rebind into a tuple, because that's what was asked
>for when the left hand side had a subscript.
>
>The reason that the examples given at the top of the thread fail
>in such strange ways is simply that '+=' does not check whether
>the assignment is possible before doing the addition (or concatination,
>in the specific cases cited.)
>
>To see this, you could try the first example, using explicit '+' and
>'='. I suspect it would fail in exactly the same way, with exactly
>the same side effect.
>
You can make a tuple that is more forgiving, in the spirit of Jeff Epler's
suggestion:
>>> class T(tuple):
... def __setitem__(self,i,thing):
... if self[i] is thing: return
... raise TypeError,"object doesn't support item assignment of new item"
...
>>> t = T( ([0],) )
>>> t
([0],)
>>> t[0] += [1]
>>> t
([0, 1],)
>>> t[0] = t[0] + [2]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in __setitem__
TypeError: object doesn't support item assignment of new item
And:
>>> a=t[0]
>>> a
[0, 1]
>>> a += [2]
>>> a
[0, 1, 2]
>>> t[0] = a
>>> t
([0, 1, 2],)
But:
>>> a = a + [3]
>>> a
[0, 1, 2, 3]
>>> t[0] = a
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in __setitem__
TypeError: object doesn't support item assignment of new item
Regards,
Bengt Richter
More information about the Python-list
mailing list