[Python-bugs-list] [ python-Bugs-463640 ] weird namespace phenomenon
noreply@sourceforge.net
noreply@sourceforge.net
Fri, 21 Sep 2001 13:15:04 -0700
Bugs item #463640, was opened at 2001-09-21 11:26
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=463640&group_id=5470
Category: Python Interpreter Core
>Group: Not a Bug
>Status: Closed
>Resolution: Invalid
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
>Assigned to: Tim Peters (tim_one)
Summary: weird namespace phenomenon
Initial Comment:
# == module f.py
y = 10
def g():
if y:
y = 100
return y
# == module h.py
import f
print f.g()
# == plop these two modules into the same directory
and 'cd' to that directory.
When you run 'python h.py' at the command line, line 6
of f.py (if y:)
creates a problem due to f being supposedly undefined.
The error is
registered as NameError or UnboundLocalError depending
on what version
of the python core you're running. Python 2.1.x says
y is being
referenced before assignment, yet if you change the
_next_ line to read
"z = 100" rather than "y = 100", the whole thing runs
fine, printing 10
(the value of f.y) at the end as expected.
This is at the very least an extreme logic quirk in
how python namespaces
work, and at worst a bug badly in need of correction
(since vsn 1.5.2 or
before).
----------------------------------------------------------------------
>Comment By: Tim Peters (tim_one)
Date: 2001-09-21 13:15
Message:
Logged In: YES
user_id=31435
Whether a given name is local or global in a given scope is
a property determined at compile-time, not at runtime. See
the Reference Manual for details. In brief, if a name is
bound ("assigned to") *anywhere* in the body of a function,
that name is local throughout the entire function. You
assign to y in the body of g(), therefore y is a local
variable everywhere in g(), and you reference y's value in g
() before giving it a value (hence it's an unbound local at
the time you first reference it, hence UnboundLocalError in
recent Pythons). The y in the body of g() has nothing to
do with the module-level vrbl y. If you intended to
reference the module-level vrbl y, then you need to put
global y
as the first statement in g().
But it's impossible for me to guess what you intended --
and it's also impossible for Python.
If you're familiar with C, it's exactly the same as
int y = 10;
int g() {int y; if (y) y = 100; return y;}
except that in C you'd get random crap out of that function
(due to referencing an uninitialized auto) instead of a
reliable exception. The difference is that Python doesn't
have explict declarations for local variables, but the fact
that you assigned to y within the body of g makes y a local
just as much as y is function-local in the C example above.
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=463640&group_id=5470