On Thu, 13 Nov 2008 10:16:59 -0700, Joe Strout 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]
This is a common trick, often used for things like caching. One major advantage is that you are exposing the cache as an *optional* part of the interface, which makes testing easier. For example, instead of a test that looks something like this: cache = get_access_to_secret_cache() # somehow modify(cache) result = function(arg) restore(cache) assert something_about(result) you can simple do this: result = function(arg, _cache=mycache) assert something_about(result) Periodically people complain that Python's mutable default argument behaviour is a problem, and ask for it to be removed. I agree that it is a Gotcha that trips up newbies, but it is far to useful to give up, and simple caching is one such reason. > 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? I've used this myself, but to me it feels more icky than the semi-private argument trick above. -- Steven -- http://mail.python.org/mailman/listinfo/python-list