using "private" parameters as static storage?

Arnaud Delobelle arnodel at googlemail.com
Fri Nov 14 17:16:08 EST 2008


Joe Strout <joe at strout.net> writes:

> On Nov 13, 2008, at 3:23 PM, Arnaud Delobelle wrote:
>
>> Aaron Brady <castironpi at gmail.com> 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.

Check the wraps() function in the functools module.  I think I wrote
this decorator before it came into the standard library.

-- 
Arnaud
 



More information about the Python-list mailing list