On Nov 13, 4:13 pm, Paul McGuire <[EMAIL PROTECTED]> wrote:
> On Nov 13, 3:08 pm, Aaron Brady <[EMAIL PROTECTED]> wrote:
>
>
>
> > 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.- Hide quoted text -
>
> > - Show quoted text -
>
> Initialization does not have to be in the body of the method.
>
> >>> def spam():
>
> ...       spam._count[0] += 1  #<--- how to initialize? see below
> ...       return "spam " * spam._count[0]
> ...>>> spam._count = [2] # just initialize it, and not necessarily to 0
> >>> spam()
> 'spam spam spam '
> >>> spam()
>
> 'spam spam spam spam '
> >>> spam()
>
> 'spam spam spam spam spam '


That is actually susceptible to a subtle kind of bug:

>>> def spam( ):
...     spam._count[0] += 1
...     return "spam " * spam._count[0]
...
>>> spam._count=[2]
>>> spam()
'spam spam spam '
>>> f= spam
>>> f()
'spam spam spam spam '
>>> spam= 'spam and eggs'
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in spam
AttributeError: 'str' object has no attribute '_count'

It would be worse if you assigned 'spam' to another function!  Of
course one option is 'just don't do that', which is alright.  Adding
the self parameter is just a second option, if you need the function
to change names.  Though the decorator is a nice place for the
initialization.
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to