Nested scopes: why is it weird?

Scott Long scott at swiftview.com
Fri Sep 7 12:20:00 EDT 2001


Nested scopes seem like a nice addition (of course!) but there are some
weird things about it. Take a look:

>>> from __future__ import nested_scopes
>>> def a():
...   def b():
...     k = x
...     print k
...   x = 1
...   b()
...
>>> a()
1

Right, this is what you would expect. But how about this?

>>> from __future__ import nested_scopes
>>> def a():
...   def b():
...     k = x
...     x = 0
...     print k
...   x = 1
...   b()
...
>>> a()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 7, in a
  File "<stdin>", line 3, in b
UnboundLocalError: local variable 'x' referenced before assignment

Here is my explanation for this (tell me if I'm wrong):

During pass #1 of compilation, the statement "x = 0" in b() binds x as a
local variable local to b(). During execution, k = x executes *before* x
has been assigned, resulting in this flamage.

My first beef here is, why is the exception called UnboundLocalError?
The variable is certainly bound (into the local scope), it simply has
not been assigned. Why not call it UninitializedLocalError? I know it
isn't going to change, I'm just asking.

But my main concern is that this way of selecting a binding seems very
unintuitive. Shouldn't the first statement referencing x be the
statement that specifies the binding of x? In this case, shouldn't "k =
x" cause x to get bound as a free variable, not a local to b()? I'm not
claiming that this is a bug. I am curious as to why it was decided that
things are going to work this way. It makes assignment to a variable in
an enclosing scope impossible!

Regards,
Scott



More information about the Python-list mailing list