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