Adding a feature (static data) to a language that doesn't really support
it may alway be a bit of hack (unfortunately, python doesn't have neither
static nor private qualifiers )-:  

Wasn't one problem to keep the global namespace clean, and to prevent the
garbage collector from cleaning up the 'static' data of interest? From
other mesages (python list) I concluded Bob's function of interest, using
those 'static' data, relates to module random. So why not adding this all
to module random's namespace? 
A) setattr(random, 'pubData', [0]) creates 'semi-static' data, but that's
not interesting because it's very public.
B) a class seems to me always the way to go when both, data and methods,
are tied together. (how would you acces n in your C example if you later
on like to add another function using n ?)
C) the persistance of n[] in Bobs original function(n=[0]) may be not
documented, but seems to be intentional and not a compiler bug as
indicated by random.count.func_defaults below. (that was a question in an
earlier message)
 It survived all the abuse I could think of: re-definition, module reload,
garbage collector.

Maybe someone (Sean Reifschneider?) can comment on how safe this really
is.

 - Horst

So below is my version of 'ugliness', w/o requiring module __future__. 
Most of the code is just for demo purposes - the essential code segments
are mentioned above.

###########################################################

import random   # module to be extended
import gc       # to look at garbage

class Counter:      # the standard approach
    def __init__(self):
        self.__count = 0
    def count(self):
        self.__count += 1
        return self.__count

def test():
    print "random.count() from test(): ", random.count()
    random.counter.count()  # silently increment
    
if __name__ == '__main__':
    # add semi-static, public data to random's name space:
    setattr(random, 'pubData', [0])  

    # add protected counter to random's name space;
    setattr(random, 'counter', Counter())  

    # add func() to random's name space:
    def func(n=[0]):      # does not have to be inline
        """ get fancy here with unique start or allow set/reset """
        n[0] += 1
        return n[0]
    setattr(random, 'count', func)  
    def func(): print "redefined func()"   #overwrite previous
    func()

    print "in main - random.count: ", random.count()
    test()
    print " - garbage collection - bad items: ", gc.collect()
    reload(random)
    print "... and again: ",
    test()
    print "same for random.counter.count()", random.counter.count()

    print "\n Now attributes of random.count: \n", dir(random.count)
    #print random.count.__doc__
    print " - random.count.func_defaults: ", random.count.func_defaults

###########################################################


On Fri, 4 Oct 2002, Bob Miller wrote:

> Those of you who were at the clinic last night know that I
> was asking for help on a weird limitation of Python.
> 
> The problem:  Consider the function, foo(), in this C program.
> 
>       #include <stdio.h>
> 
>       int foo()
>       {
>           static int n = 0;
>           return ++n;
>       }
> 
>       main()
>       {
>           int n1 = foo();
>           int n2 = foo();
>           printf("%d %d\n", n1, n2);
>           return 0;
>       }
> 
> It keeps state around between calls, but does not have extra names in
> any nonlocal namespaces.
> 
> How would you write a function in Python that does the same?
> (Note, I don't want a solution that only returns successive numbers.
> I might use this to return successive lines of a file or calculate
> successive permutations of a sequence or whatever.)
> 
> The solution: For some reason, this apparently simple problem doesn't
> have any good solutions (that I'm aware of).  Here's the best I can
> do.
> 
>       def foo():
>           n = [0]
>           def bar():
>               n[0] += 1
>               return n[0]
>           return bar
>       foo = foo()
> 
> That reuses the single global name, foo.  First, foo holds a function
> that returns the function we need.  Then we set foo to the returned
> function.  The original function is not accessible, AFAIK.
> 
> -- 
> Bob Miller                              K<bob>
> kbobsoft software consulting
> http://kbobsoft.com                     [EMAIL PROTECTED]
> _______________________________________________
> Eug-LUG mailing list
> [EMAIL PROTECTED]
> http://mailman.efn.org/cgi-bin/listinfo/eug-lug
> 

_______________________________________________
Eug-LUG mailing list
[EMAIL PROTECTED]
http://mailman.efn.org/cgi-bin/listinfo/eug-lug

Reply via email to