accessing a functions var from a subfunction.

Alex Martelli aleax at aleax.it
Mon Apr 14 10:30:38 EDT 2003


Sebastian Wilhelmi wrote:

> Hi,
> 
> I would like to do the following:
> 
> -------8<-------8<-------8<-------8<-------
> def test ():
>     count = 0
>     def inc_count ():
>         count += 1
>     inc_count ()
>     inc_count ()
>     print count
> 
> test ()
> -------8<-------8<-------8<-------8<-------
> 
> This doesn't work (and I even understand, why ;-)

Specifically: a nested function cannot *RE-BIND* a variable of
an outer function.

> One solution is the following, which I however do not see as very
> clean or nice.
> 
> -------8<-------8<-------8<-------8<-------
> def test ():
>     count = [0]
>     def inc_count ():
>         count[0] += 1
>     inc_count ()
>     inc_count ()
>     print count[0]
> 
> test ()
> -------8<-------8<-------8<-------8<-------
> 
> Now my question: Is there some way to achieve this with a nicer
> syntax?

Depends on your tastes in syntax, e.g.:

def test():
    class Bunch: pass
    loc = Bunch()
    loc.count = 0
    def inc_count():
        loc.count += 1
    inc_count()
    inc_count()
    print loc.count

or:

def test():
    test.count = 0
    def inc_count():
        test.count += 1
    inc_count()
    inc_count()
    print test.count

and no doubt quite a few others.

> Using 'global' would not count, as that would make a variable
> unnecessarily known to the outside.

The two solutions above outlined differ in this respect -- variable
'loc' in the former is local to function test, while function attribute
test.count in the latter is "known to the outside" (it survives each
execution of test and can be examined "from the outside").


Class Bunch (or some highly refined version thereof) IS typically
around whenever I program, see for example:

http://mail.python.org/pipermail/python-list/2002-July/112007.html

for a typical presentation.  Having available the MetaBunch there
described, I'd start the function as follows:

def test():
    class Bunch(MetaBunch): count=0
    loc = MetaBunch()
    def inc_count():
        loc.count += 1

etc.  I do find such constructs often handy...


Alex





More information about the Python-list mailing list