Assignment operator?

Steve Holden sholden at holdenweb.com
Thu Apr 18 11:05:25 EDT 2002


"Ante Bagaric" <abagaric_NOSPAM at rest-art.hr> wrote ...
>
> After reading that PEP about static namespaces I'm now pretty confused
with
> the behaviour of the += operator.
>
It might have been helpful to quote the PEP number. I'm gyuessing you mean
PEP 227, from

    http://www.python.org/peps/pep-0227.html

> The PEP states that if there is a binding of certain name anywhere within
> the body of the function, it is considered local. Then it states that
> binding operations include stuff like def, for, except... AND assignment.
>
Correct. The compiler makes a static analysis of each function body, and
every name which is assigned within the function body is regarded as local,
even if there are other uses, unless it's explicitly declared to be global.

This sometimes leads to oddities like:

>>> a = 3
>>> def myfunc():
...     print a
...     a = 4
...
>>> myfunc()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in myfunc
UnboundLocalError: local variable 'a' referenced before assignment

The weird thing here is that if you remove the "print" statement the
function raises no exception. It doesn't do much, but that's another story.

> I guess that for some reason operator += is considered an 'assignment'
> (because it is often called 'one of assignment operators') but is it
really?
> Is 'a = a + 2' the _same_ as 'a += 2'? I don't think it is, or should be.
> The 'a = a + 2' means 'store the value of a + 2 to the variable a' and 'a
+=
> 2'
> means 'increment a by 2'.
>
Indeed, +=. -= and the rest are referred to as "augmented assignment
operators". Whether or not you think that 'a = a + 2' should be the same as
"a += 2" is a matter of choice. The implementation, however, clearly allows
operators to implement in-place update on mutable objects *if they choose*,
but does not require it.

Obviously, immutables must implement augmented assignment by re-binding the
name to a new object, otherwise

>>> a = 3
>>> a += 2
>>> a
5

would not be possible.

> The fact is that Python already behaves exactly like that. If you say
>
> >>> li = [1,2,3]
> >>> li2 = li
> >>> li += [4,5]
> >>> li is li2
> 1
>
> but if you say
>
> >>> li = [1,2,3]
> >>> li2 = li
> >>> li = li + [4,5]
> >>> li is li2
> 0
>
Indeed. Thr PEPs aren't all proposals for the future: you might notice that
in

    http://www.python.org/peps/

PEP 227 is listed in the "finished PEPs" section. It's one of Python's
charms, or weaknesses, depending on how authoritative you expect your
documentation to be, that it's quite possible to have features in the
language whose specifications include such extracts as

"""XXX Explain the examples"""

"""XXX need some counterexamples"""

and (my favorite)

"""XXX Jeremy, is this still the case?""".

However, we should remember that the Python development team are humans, and
it's much easier to bitch about this sort of thing than it is to roll up
one's sleeves and fix them.

> According to this, += operator can't be though of as an 'assignment
> operator'.
> And conversely, it shouldn't cause the compiler to consider 'foo' to be
> local
> if there is 'foo += stuff' somewhere within the body of the function.
> After all, 'foo.append(stuff)' or 'foo.extend(stuff)' don't do it.
>
> Or there is something I didn't quite understand?
>
I think what you haven't understood is the update in-place semantics that
mutable object implementations *may* choose to adopt. Otherwise you seem to
have it down pat.

regards
 Steve







More information about the Python-list mailing list