Scoping "bug" ?

Tim Peters tim_one at email.msn.com
Fri Aug 18 14:07:34 EDT 2000


[Kevin Bailey]
> I get the feeling that this isn't a bug but I'd be quite disappointed
> if this is intended behavior:
> ...

Definitely intended.  Python has no declarations (apart from the rarely-used
"global"), so has to use some other means to determine whether a name is
local or global.  This decision is made at compile-time, not run-time.
Simplifying a bit, a name is local to a block if and only if it's "assigned
to" (bound) *somewhere* in that block.  Emphasize again that this is a
static, compile-time decision; it has nothing to do with which paths thru
the code happen to be taken at run-time.

> Python 1.5.2 (#2, Jun  9 2000, 16:02:51)  [GCC 2.95.2 19991024 (release)]
> Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
> >>> a = 1
> >>> def fun1(x):
> ...     if x:
> ...             print a
> ...
> >>> def fun2(x):
> ...     if x:
> ...             print a
> ...     else:
> ...             a = 2
> ...
> >>> fun1(1)
> 1
> >>> fun2(1)
> Traceback (innermost last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 3, in fun2
> NameError: a
> >>>

Note that in 1.6 and beyond, this raises the more descriptive
UnboundLocalError instead.  If Python *required* declarations, fun2 would
look like

def fun2(x):
    local a
    if x:
        print a
    else:
        a = 2

and then it would be obvious to you (well, I hope <wink>) that the "print a"
is referencing an uninitialized local variable.  Python doesn't have a
"local" declaration, but the *effect* is exactly the same.

> If the goal here is to avoid errors,

The goal is to kick you in the teeth for referencing a name you've never
given a value to.

> the interpretter should spit out a warning instead of perverting
> the scoping rules.

The scoping rules are consistent here, and indeed they *would* be some
perverse form of dynamic scoping if a name were either local or global
depending on which code you happened to execute before reaching a line.  The
decision is made at compile-time instead, and is enforced.

you'll-get-over-your-outrage-before-"a"-grows-a-sensible-
    binding-out-of-thin-air<wink>-ly y'rs  - tim






More information about the Python-list mailing list