Behavior of += (was Re: [Python-Dev] Customization docs)
Bengt Richter
bokr at oz.net
Tue Jun 4 18:11:27 EDT 2002
On 4 Jun 2002 17:51:15 GMT, "Donn Cave" <donn at u.washington.edu> wrote:
>Quoth Chris Barker <Chris.Barker at noaa.gov>:
>| Huaiyu Zhu wrote:
>|> Great explanation! The problem stems from the fact that the current +=
>|> operator implements two semantically distinct operations, chosen according
>|> to some properties of the operands.
>|
>| exactly, and it wa kind of a weird decision. Personally, I feel the only
>| compelling reason to add The += (and friends) operator was to support
>| in-place addition, most notably for Numeric arrays. Frankly it ought to
>| just be disallowed for non-mutable types, but all the folks that want it
>| for integers would scream. to be honest, I've kind of lost track of why
>| it is a good idea for numbers to be immutable, but that's another topic!
>
>That would be almost as cool as the old implementations of FORTRAN
>where you could change the value of 1.
>
>|> I'd imagine that at some future time there would be a desire to split += to
>|> two distinct operators, one for true in-place operator and one for the fake
>|> one currently implemented for immutables. That would remove the spurious
>|> exceptions for mutable members of immutable structures.
>|
>| Do we really need a new notation? is a = a + b so bad?
>
>No, it's fine.
>
But see below...
>| ... In fact, are the
>| current semantics of += s bad, or should this bug just be fixed?
>
>Not really - the current semantics are actually better than the fixed
>version, inasmuch as they are at least consistent. As I interpret the
>proposal, the fixed += would sometimes work without rebinding (if the
>object supports it) and sometimes would be an assignment (falling back
>to +.) To me, to allow an object to dictate its relationship to its
>computational environment like that is anathema.
>
>...
>| By the way, the += and friends operators also cause similar confusion
>| with name scopes in functions, += is assumed to be a re-bind, when it
>| isn't necessarily intended to:
>|
>| >>> l = [1,2,3]
>| >>> def test():
>| ... l += [4]
>| ...
>| >>> test()
>| Traceback (most recent call last):
>| File "<stdin>", line 1, in ?
>| File "<stdin>", line 2, in test
>| UnboundLocalError: local variable 'l' referenced before assignment
>|
>| but:
>|
>| >>> def test2():
>| ... l.extend([4])
>|
>| >>> test2()
>| >>> l
>| [1, 2, 3, 5]
>|
>| Works just fine. Perhaps Huaiyu is right, we need different operators.
>| However, then the operator for incrementing a non-mutable would just be
>| a synonym for a = a + b, which looks like unnecessary syntactical sugar
>| to me.
>
>Yes.
>
Here is a contrived case where += lets you use a
mutable-lhs-target-expression-with-side-effect and
get only one side effect. There are obviously other
ways, but at least += is convenient (and presumably
faster in a case like this).
>>> a=[0]
>>> def foo():
... print 'side effect'
... return a
...
>>> foo()
side effect
[0]
>>> foo()[0]+=1
side effect
>>> a
[1]
>>> foo()[0] = foo()[0]+1
side effect
side effect
>>> a
[2]
Regards,
Bengt Richter
More information about the Python-list
mailing list