[Tutor] scoping rules

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Sun, 6 Jan 2002 14:24:43 -0800 (PST)


On Sun, 6 Jan 2002, dman wrote:

> | Does this mean that i will not be able to increment a (908) (defined in the
> | enclosing function)
> | inside the inner function?
> 
> You are right.  Here's what's going on :
> 
> When you have an assignment statement, a new local variable is
> created.  The compiler (with the nested scopes modifications) will
> flag those names as being local.  When you have the "a+=1" line the
> compiler sees that 'a' is a local variable.  Thus you get the
> "UnboundLocal" error when you try and reference 'a' (to get it's
> original value).  If you say 'global' it works only because 'a' is at
> the module level.  If you say 'global a' and then assign to 'a', 'a'
> is going to be at the module level.  For example this won't work :
> 
> def f() :
>     a = 908
>     def g() :
>         global a
>         a+=1
>     g()
> f()


If we're really trying to make changes to the variable of an enclosing
class, there is an idiom we can use:


###
def f():
    a = [908]
    def g():
        a[0] += 1
    g()
    print a
###


And here it is in action:

###
>>> f()
[909]
###


This dodges the issue by assigning to an array element.  Since we're not
assigning to 'a' itself, Python knows that we're just refering to the 'a'
of our enclosing function.