Nested scopes: why is it weird?

Alex Martelli aleax at aleax.it
Fri Sep 7 12:42:47 EDT 2001


"Scott Long" <scott at swiftview.com> wrote in message
news:3B98F3B0.53AC2524 at swiftview.com...
> 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