On Nov 13, 11:16 am, Joe Strout <[EMAIL PROTECTED]> wrote: > One thing I miss as I move from REALbasic to Python is the ability to > have static storage within a method -- i.e. storage that is persistent > between calls, but not visible outside the method. I frequently use > this for such things as caching, or for keeping track of how many > objects a factory function has created, and so on. > > Today it occurred to me to use a mutable object as the default value > of a parameter. A simple example: > > def spam(_count=[0]): > _count[0] += 1 > return "spam " * _count[0] > > >>> spam() > 'spam ' > >>> spam() > 'spam spam ' > > This appears to work fine, but it feels a little unclean, having stuff > in the method signature that is only meant for internal use. Naming > the parameter with an underscore "_count" makes me feel a little > better about it. But then, adding something to the module namespace > just for use by one function seems unclean too. > > What are your opinions on this idiom? Is there another solution > people generally prefer? > > Ooh, for a change I had another thought BEFORE hitting Send rather > than after. Here's another trick: > > def spam2(): > if not hasattr(spam2,'count'):spam2.count=0 > spam2.count += 1 > return "spam2 " * spam2.count > > This doesn't expose any uncleanliness outside the function at all. > The drawback is that the name of the function has to appear several > times within itself, so if I rename the function, I have to remember > to change those references too. But then, if I renamed a function, > I'd have to change all the callers anyway. So maybe this is better. > What do y'all think?
Worse yet, if you define a duplicate object at the same scope with the same name later, it breaks all your references within the function to itself. 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. @self_param def spam( self ): self._count[0] += 1 #<--- how to initialize? return "spam " * self._count[0] Only problem is, how do you initialize _count? Perhaps 'self_param' can take some initializers, and just initialize them off of **kwargs in the construction. @self_param( _count= [] ) def spam( self ): self._count[0] += 1 return "spam " * self._count[0] Looks really pretty (imo), but untested. -- http://mail.python.org/mailman/listinfo/python-list