copy on write

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Feb 2 04:16:40 EST 2012


On Thu, 02 Feb 2012 19:11:53 +1100, John O'Hagan wrote:

> You're right, in fact, for me the surprise is that "t[1] +=" is
> interpreted as an assignment at all, given that for lists (and other
> mutable objects which use "+=") it is a mutation. Although as Steven
> says elsewhere, it actually is an assignment, but one which ends up
> reassigning to the same object.
>  
> But it shouldn't be both.

Do you expect that x += 1 should succeed? After all, "increment and 
decrement numbers" is practically THE use-case for the augmented 
assignment operators.

How can you expect x += 1 to succeed without an assignment? Numbers in 
Python are immutable, and they have to stay immutable. It would cause 
chaos and much gnashing of teeth if you did this:

x = 2
y = 7 - 5
x += 1
print y * 100
=> prints 300

So if you want x += 1 to succeed, += must do an assignment.

Perhaps you are thinking that Python could determine ahead of time 
whether x[1] += y involved a list or a tuple, and not perform the finally 
assignment if x was a tuple. Well, maybe, but such an approach (if 
possible!) is fraught with danger and mysterious errors even harder to 
debug than the current situation. And besides, what should Python do 
about non-built-in types? There is no way in general to predict whether 
x[1] = something will succeed except to actually try it.

> I can't think of another example of (what
> appears to be but is not) a single operation failing with an exception,
> but still doing exactly what you intended.

Neither can I, but that doesn't mean that the current situation is not 
the least-worst alternative.


>> I can't think of any way out of this misleadingness, although if you
>> can that would be pretty awesome.
> 
> In the case above, the failure of the assignment is of no consequence. I
> think it would make more sense if applying "+=" to a tuple element were
> treated (by the interpreter I suppose) only on the merits of the
> element, and not as an assignment to the tuple.

How should the interpreter deal with other objects which happen to raise 
TypeError? By always ignoring it?

x = [1, None, 3]
x[1] += 2  # apparently succeeds

Or perhaps by hard-coding tuples and only ignoring errors for tuples? So 
now you disguise one error but not others?



-- 
Steven



More information about the Python-list mailing list