using "private" parameters as static storage?
Matimus
mccredie at gmail.com
Thu Nov 13 12:38:11 EST 2008
On Nov 13, 9: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 '
>
Don't Do this, it is confusing and there are definitely (many) better
facilities in python for handling saved state.
> 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 is definitely preferred over the first. However the preferred
method is just to use a class. Preserving state is what classes are
for.
>>> class Spam(object):
... def __init__(self):
... self._count = 0
... def spam(self):
... self._count += 1
... return " ".join("spam" for _ in xrange(self._count))
...
>>> x = Spam()
>>> print x.spam()
spam
>>> print x.spam()
spam spam
>>> print x.spam()
spam spam spam
It also gives you the ability to have two compleately separate
instances of the same state machine.
>>> y = Spam()
>>> print y.spam()
spam
>>> print y.spam()
spam spam
>>> print y.spam()
spam spam spam
>>>
You can use it like a function if you need to for convenience or
backwards compatibility.:
>>> spam = Spam().spam
>>> print spam()
spam
>>> print spam()
spam spam
>>> print spam()
spam spam spam
Or:
>>> class Spam(object):
... def __init__(self):
... self._count = 0
...
... def spam(self):
... self._count += 1
... return " ".join("spam" for _ in xrange(self._count))
...
... __call__ = spam
...
>>> spam = Spam()
>>> print spam()
spam
>>> print spam()
spam spam
>>> print spam()
spam spam spam
Matt
More information about the Python-list
mailing list