On Nov 13, 2008, at 3:23 PM, Arnaud Delobelle wrote:

Aaron Brady <[EMAIL PROTECTED]> writes:

One way around it, which I like the idea of but I'll be honest, I've
never used, is getting a function a 'self' parameter.  You could make
it a dictionary or a blank container object, or just the function
itself.
...
Rummaging through my ~/python/junk/ I found the almost exact same:

class NS(object):
   def __init__(self, dict):
       self.__dict__.update(dict)

def static(**vars):
   ns = NS(vars)
   def deco(f):
       return lambda *args, **kwargs: f(ns, *args, **kwargs)
   return deco

@static(ncalls=0, history=[])
def foo(ns, x):
  ns.ncalls += 1
  ns.history.append(x)
  print "Number of calls: %s\nHistory:%s" % (ns.ncalls, ns.history)

Thanks, Arnaud (and Aaron), that's really clever. I was thinking this morning that something like this might be possible: a decorator that adds the static storage with some standard name. I really like how you've set this so that the static data is initialized right in the decorator; that makes the intent very clear and hard to screw up.

My only regret with this one is the need to add "ns" to the parameter list. That makes it lok like part of the signature, when really (in intent) it is not. If we have to add something to the parameter list, we may as well do this:

def foo(x, _ns=NS(ncalls=0, history=[])):
   ...

and skip the decorator. Then at least it's clear that this parameter isn't really intended for callers. On the other hand, I guess the decorator actually changes the signature as seen by the calling code, which is a good thing. Rearranging the parameter order in the decorator a bit, we could make this so that the intent is clear to the reader, as well as enforced by the interpreter.

Neat stuff, thank you!

Best,
- Joe




--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to