nested function scopes

Terry Reedy tjreedy at udel.edu
Thu Dec 11 13:54:24 EST 2003


"Nils Grimsmo" <nilsgri at idi.ntnu.no> wrote in message
news:3fd83270$1 at news.broadpark.no...
> hi,
>
> i'm having some trouble nesting functions. consider the following:
>
>
> def h():
>     x = 1
>     def g():
>         print x # ok, x is taken from h
>     g()
>
> def f():
>     x = 1
>     def g():
>         print x # this is not ok
>         x = 2 # this implies that x is local to g
>     g()
>
> h() # ok
> f() # UnboundLocalError: local variable 'x' referenced before assignment
...
> how do i declare that x belongs to the parent function, so that i can do
> assignments to it?

Currently you cannot.  As you probably know, 'global' declares that x
belongs to the module so you can assign to as well read it.  This fall,
there was an extended discussion on pydev (at least 30 posts, I am sure) on
the subject of extending the idea of global to allow assignment to
intermediate scopes.  Would such be desireable?  If so, what syntax?  See
python.org for B. Cannon's summaries or link to archives.  Current bottom
line: no change.

> do i have to put it into a compound object?

If compound = mutable collection, yes.  Your example revised:

def f():
     x = [1]
     def g():
         print x[0]
         x[0] = 2
      g()

The ease of doing this and the ugliness or other problems with proposed
alternatives inhibits change.

> it would be very handy to be able to do this if i have nested functions
> that use a lot of varables. only passing the variables you assign to as
> packed compound parameters is a bit ugly, since what subset of all
> variables this is might change.

You do not have to 'pass' the compound since you have read access to mutate
it.

> i cannot say i like the python scope rules yet. they probably are
> practical, but they seem complicated an unstructured to me.

They were simpler before nested scopes were introduced ;-).  You can program
without them if you wish.

> take for example
>
> class C:
>     y = 0
>     def f(self):
>         print y

> which does not work unless y is a global. i understand and agree too why
> y is not taken from the instance (self), because of the way classes and
> instances relate in python. what i do not understand, is why y is not
> taken from C, but from global, when nothing is specified. in the
> previous example, with the functions h() and g(), g() took x from h().
> why should not f() take y from C?

This is a different kettle of fish.  Classes, though callable, are not
functions and methods are not nested functions.  Neither class nor instance
methods can be called during class construction because neither the class
nor instances thereof even exist.  In any case, there is already a mechanism
for accessing class attributes: C.y in this case.  Use it.

Terry J. Reedy







More information about the Python-list mailing list