On Mar 18, 7:17 am, "Dustan" <[EMAIL PROTECTED]> wrote: > On Mar 18, 5:26 am, "Gabriel Genellina" <[EMAIL PROTECTED]> > wrote: > > > > > En Sat, 17 Mar 2007 13:31:01 -0300, Dustan <[EMAIL PROTECTED]> > > escribió: > > > >http://dustangroups.googlepages.com/privateattributesinpython > > > > This is something that I just threw together this morning, after a > > > eureka moment. It's a way of creating private class attributes and > > > static function variables (I'm not 100% sure if that's the correct > > > terminology, but you get what I mean). I haven't tried to create > > > private instance attributes, mainly because it would just be too > > > difficult, and it would be awful syntax. I'm not considering actually > > > using this, but I do have a couple questions about it. > > > I feel so dumb, but I can't see how to use it, or what's for. Perhaps an > > example? > > > -- > > Gabriel Genellina > > There are two examples - one demonstrating static function variables > and one demonstrating private class attributes. Both perform some kind > of counting. The function returns how many times it's been called. > Here it is: > > @PrivateDataEngine(numCalls = 0) > def testPrivateStaticFunctionVariables(internalData): > """returns the number of times this function has been called.""" > internalData.numCalls += 1 > return internalData.numCalls > > There's a comment explaining how the decorator works on the page I > linked you to. > > A common pythonic workaround for this is something like this: > > def testMutableDefaultArgs(_cache = {'internalData':0}): > """returns the number of times this function has been called.""" > _cache['internalData'] += 1 > return _cache['internalData'] > > The default argument only gets evaluated once, and since it's mutable > and being modified in the function, it magically becomes > {'internalData':1} after 1 call and {'internalData':1348372} after > 1348372 calls. > > The other example, explaining private class attributes, has a method > getNumInstances that returns how many instances have been created. > Here that is: > > class TestPrivateClassAttributes(object): > # pca here obviously stands for Private Class Attributes. > pcaManager = PrivateDataEngine(numInstances = 0) > > # Notice that the internal data is an implicit parameter that > comes first, > # even before the self parameter. > @pcaManager > def __init__(internalData, self): > internalData.numInstances += 1 > > @staticmethod > @pcaManager > def getNumInstances(internalData): > return internalData.numInstances > > # Don't forget to delete the pcvManager, or it will have all been > in vain. > del pcaManager > > I'm thinking this is going to look rather ugly when the text gets > wrapped; that's why I linked to an external page in the first place. > > Notice it requires more advanced usage of the PrivateDataEngine if you > want multiple functions to have access to the same data, as you > normally would in a class. > > Note also that the double-decorated method getNumInstances requires > that staticmethod be the first decorator. This is equivalent to the > code "getNumInstances = staticmethod(pcaManager(getNumInstances))". I > got an error when I tried it with pcaManager preceding staticmethod, > so my educated guess is that staticmethods are somehow specially > recognized by the class, and therefore they have to actually BE > staticmethods, not dressed over by a pcaManager. > > Now that I think of it, for clarity, pcaManager may not have been a > good name for the function returned by PrivateDataEngine; pcaDecorator > would have been better, seeing as it IS a decorator. Perhaps I'll > change that soon. > > The pythonic way would be: > > class TestPythonsPrivateClassAttributes(object): > _numInstances = 0 > > def __init__(self): > # class attributes can be accessed from self. > self.numInstances += 1 > > @staticmethod > def getNumInstances(internalData): > return self.numInstances > > It should immediately stick out as being much more concise > syntactically, and therefore much less bug-prone. > > Obviously, these examples are a lot like "Hello, World!" in their > usefulness; one would very rarely want to track how many times a > function has been called. > > Hope that helps.
I forgot to note that the 'pythonic' ways are untested (and remain so, as far as I know). -- http://mail.python.org/mailman/listinfo/python-list