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