Augmented assignment (was Re: Something in the function tutorial confused me.)

Roel Schroeven rschroev_nospam_ml at fastmail.fm
Sat Aug 11 10:19:51 EDT 2007


Aahz schreef:
> In article <m3hvi.37606$G23.6240 at newsreading01.news.tds.net>,
> Neil Cerutti  <horpner at yahoo.com> wrote:
>> On 2007-08-11, Alex Martelli <aleax at mac.com> wrote:
>>> Neil Cerutti <horpner at yahoo.com> wrote:
>>>    ...
>>>> The Python Language Reference seems a little confused about the
>>>> terminology.
>>>>
>>>>   3.4.7 Emulating numeric types
>>>>   6.3.1 Augmented assignment statements
>>>>
>>>> The former refers to "augmented arithmetic operations", which I
>>>> think is a nice terminology, since assignment is not necessarily
>>>> taking place. Then the latter muddies the waters.
>>> Assignment *IS* "necessarily taking place"; if you try the augmented
>>> assignment on something that DOESN'T support assignment, you'll get an
>>> exception.  Consider:
>>>
>>>>>> tup=([],)
>>>>>> tup[0] += ['zap']
>>> Traceback (most recent call last):
>>>   File "<stdin>", line 1, in <module>
>>> TypeError: 'tuple' object does not support item assignment
>>>
>>> Tuples don't support item ASSIGNMENT, and += is an ASSIGNMENT,
>>> so tuples don't allow a += on any of their items.
>>>
>>> If you thought that += wasn't an assignment, this behavior and
>>> error message would be very problematic; since the language
>>> reference ISN'T confused and has things quite right, this
>>> behavior and error message are perfectly consistent and clear.
>> Thanks for the correction. I was under the illusion that sometimes
>> augmented assignment would instead mutate the object.
> 
> Although Alex is essentially correct, the situation is a bit more complex
> and you are correct that augmented assignment allows the object to decide
> whether to mutate in place.  However, the critical part of Alex's point
> is what you need to focus on: it's the *tuple* in Alex's example that
> intercepts the assignment call, not the list contained in the tuple.
> 
> Obviously, you can easily work around it:
> 
>>>> t = ([],)
>>>> l = t[0]
>>>> l += ['foo']
>>>> t
> (['foo'],)

I'm missing something here, I think. As far as I can tell, the language 
reference says that the target is evaluated before the augmented 
assignment is performed. If that's the case, I don't see how the tuple 
in Alex' example has anything to with it: the assignment is to the list, 
not the tuple.

And watch this (Python 2.4.2):

 >>> tup = ([],)
 >>> tup[0] += ['zap']

Traceback (most recent call last):
   File "<pyshell#10>", line 1, in -toplevel-
     tup[0] += ['zap']
TypeError: object does not support item assignment

So far that's the same as Alex' example, but look at the value of the 
tuple now:

 >>> tup
(['zap'],)

Despite the TypeError, the list *has* changed.

-- 
If I have been able to see further, it was only because I stood
on the shoulders of giants.  -- Isaac Newton

Roel Schroeven



More information about the Python-list mailing list