[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>.