Steven D'Aprano <ste...@remove.this.cybersource.com.au> writes: > There's a practical reason too. You create a new Foo instance, mutate > it with the augmented assignment operator, and then a tenth of a > millisecond later the garbage collector throws it away because it has > a reference count of zero.
Only in this specific example. A function can easily return a well-known object, which it's sensible to mutate. Besides, class mumble (object): pass mumble().foo = 1 is accepted without fuss, and is just as useless. I think I see the confusion here. * Python assignment (`=') is fairly simple. The left-hand side is analyzed syntactically: if it's a plain name then the variable it denotes is modified; otherwise an appropriate method is invoked to mutate some object. * Python augmented-assignment (`+=', for example) is inconsistent. Depending on what type of object the left-hand side evaluates to, it may /either/ mutate that object, /or/ assign a new value to the expression. What do I mean? Well, consider this function. def assg(x, y): x = y Under no circumstances does calling this function have any effect (other than wasting time and memory). But: def aug(x, y): x += y Calling this function might or might not have an observable effect, depending on the type of x. For example, x = 5 aug(x, 3) is useless, but x = [1, 2, 3] aug(x, [4]) is not. The `aug' function can be used to bypass the syntactic restriction on augmented assignment, where it makes sense: aug(func(), 17) is always syntactically valid, and may or may not be useless depending on the type of thing returned by `func'. The Python language refuses to let the programmer write something which is (a) possibly meaningful, and (b) possibly useful because augmented assignment inherits the syntactic restriction of simple assignment that the left-hand side expression designate a `place' -- i.e., one of the things that there's a rule for assigning to, e.g., VAR, EXPR[INDEX], EXPR.ID -- because it /might/ need to perform such an assignment, though it might not. My personal view is that augmented-assignment operators which work by mutation rather than assignment (e.g., `+=' on lists, rather than `+=' on numbers) are one of Python's least pleasant warts. But if they're going to exist then I think list() += [1] ought to be valid syntax, since semantically it's actually clear what it should do (namely, construct a fresh empty list, append a `1' to it, and then throw the whole thing away). Of course, tuple() += 1, is still meaningless, and ought to be an error. Of course, this removes a static error-check, but if we were petty about getting all our errors at compile time we wouldn't be writing in Python in the first place. -- [mdw] -- http://mail.python.org/mailman/listinfo/python-list