[Python-Dev] behavior of inplace operations
Tim Peters
tim.one@comcast.net
Mon, 17 Jun 2002 12:28:26 -0400
[Tim sez]
> The inplace ops in Python do "just work" to my eyes, but I expect them
> to work the way Python defines them to work,> which is quite uniform.
> For example,
>
> e1[e2] += e3
>
> acts like
>
> t0, t1 = e1, e2
> t0[t1] = t0[t1] + e3
[David Abrahams]
> But that's not even right, AFAICT. Instead, its:
>
> t0, t1 = e1, e2
> t2 = t0[t1]
> t2 += e3 # possible rebinding operation
> t0[t1] = t2
That's closer, although the "mystery" in the 3rd line is less mysterious if
the whole shebang is rewritten
t0, t1 = e1, e2
t0[t1] = t0[t1].__iadd__(e3)
That makes it clearer that the effect of the final binding is determined by
what the __iadd__ implementation chooses to return.
> ...
> Actually, that was exactly what I expected. What I didn't expect was that
> there's a guarantee that it's evaluated twice, once as part of a getitem
> and once as part of a setitem.
There is.
> ...
> I don't think it should have a reference-to-lvalue. Please, give me a tiny
> bit of credit for being able to think Pythonically. I don't see everything
> in terms of C++; I just expected Python not to do a potentially expensive
> lookup and writeback in the cases where it could be avoided. Other people,
> apparently, are also surprised by some of the cases that arise due to the
> unconditional write-back operation.
Getting single-evaluation requires picturing reference-to-lvalue, or magical
writeback proxies, or something else equally convoluted: they're unPythonic
simply because Python doesn't have stuff like that. A protocol was invented
for supporting both in-place and replacement forms of augmented assignments
uniformly, but it's a Pythonically simple protocol in that it can be
expressed *in* Python with no new concepts beyond that methods like __iadd__
exist. I don't dispute that it surprises some people some of the time, but
I submit that any other protocol would surprise some people too. Heck, even
before augmented assignments were introduced, it surprised some people that
list = list + [list2]
*didn't* extend list inplace. Overall, "other people" are nuts <0.9 wink>.