Confused by Python and nested scoping (2.4.3)
Ben Cartwright
bencvt at gmail.com
Wed Apr 19 20:05:29 EDT 2006
Sean Givan wrote:
> def outer():
> val = 10
> def inner():
> print val
> val = 20
> inner()
> print val
>
> outer()
>
> ..I expected to print '10', then '20', but instead got an error:
>
> print val
> UnboundLocalError: local variable 'val' referenced before assignment.
>
> I'm thinking this is some bug where the interpreter is getting ahead of
> itself, spotting the 'val = 20' line and warning me about something that
> doesn't need warning. Or am I doing something wrong?
Short answer: No, it's not a Python bug. If inner() must modify
variables defined in outer()'s scope, you'll need to use a containing
object. E.g.:
class Storage(object):
pass
def outer():
data = Storage()
data.val = 10
def inner():
print data.val
data.val = 20
inner()
print data.val
Long answer:
The interpreter (actually, the bytecode compiler) is indeed looking
ahead. This is by design, and is why the "global" keyword exists. See
http://www.python.org/doc/faq/programming/#what-are-the-rules-for-local-and-global-variables-in-python
Things get more complex than that when nested function scopes are
involved. But again, the behavior you observed is a design decision,
not a bug. By BDFL declaration, there is no "parentscope" keyword
analogous to "global". See PEP 227, specifically the "Rebinding names
in enclosing scopes" section: http://www.python.org/dev/peps/pep-0227/
Hope that helps,
--Ben
More information about the Python-list
mailing list