A question on modification of a list via a function invocation

Steve D'Aprano steve+python at pearwood.info
Mon Sep 4 11:07:21 EDT 2017


On Tue, 5 Sep 2017 12:34 am, Rustom Mody wrote:

> On Monday, September 4, 2017 at 5:58:18 PM UTC+5:30, ROGER GRAYDON CHRISTMAN
> wrote:
>> Or with just one function: >>> def baz(x,y):
>>  x += y
>> >>> a = 10
>> >>> b = [10]
>> >>> baz(a,a)
>> >>> a
>> 10
>> >>> baz(b,b)
>> >>> b[10, 10]
> 
> Ha Ha!  Lovely
> 
> [I was about to ask Chris if he is being serious about relating this to the
> presence of '=' ]
> 
> However if you desugar the += into __iadd__ then someone may argue
> the presence of the = is an optical illusion

I'm afraid I can't quite follow what people think this example actually
demonstrates.

Augmented assignment operators += etc. are explicitly defined as a form of
assignment, but objects are permitted to optimize the operation in terms of
in-place mutation as well.

And that is precisely what lists do.

Given lists b and c, as above, b += c is functionally equivalent to:

b.extend(c)
b = b

In this case, the assignment is a no-op, but that is not always the case. The
assignment is the cause of a notorious "WAT?" moment in Python:


py> t = ([], 0)
py> t[0] += [999]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
py> t
([999], 0)


In this case, the line t[0] += [999] is desugared into something like:

t[0].extend([999])  # succeeds
t[0] = t[0]  # fails


Of course it would be stupid if that were *literally* what Python did. Rather,
Python calls the __iadd__ method of the list, which is implemented something
like this:

def __iadd__(self, other):
    self.extend(other)
    return self

and attempts to bind the return result to the target:

temp = t[0].__iadd__([999])
t[0] = temp



The assignment is necessary to support types like tuples, ints, strings etc.
which don't perform an in-place modification.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list