using "private" parameters as static storage?
Aaron Brady
castironpi at gmail.com
Thu Nov 13 16:08:28 EST 2008
On Nov 13, 11:16 am, Joe Strout <j... at strout.net> 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.
More information about the Python-list
mailing list