
On Fri, 1 May 2009 06:59:55 am Jared Grubb wrote:
On 30 Apr 2009, at 12:22, Scott David Daniels wrote:
This is slightly better (name change as in Antoine Pitrou's comment):
class cached(object):
def __init__(self, function): self._function = function self._cache = {}
def __call__(self, *args): try: return self._cache[args] except KeyError: self._cache[args] = self._function(*args) return self._cache[args]
def expire(self, *args): del self._cache[args]
The only thing I dislike is how many dictionary lookups are required in order to return the value after it's been cached. I count 4 lookups (object.prop, prop.__call__, self._cache, and self._cache[args]). These add up, especially if object.prop could have returned the value immediately without having to go through so much indirection (but this is not currently possible)
But you shouldn't be comparing a cheap attribute requiring one key lookup to a cache requiring four lookups. You should be comparing an expensive function call to four lookups. If the function isn't expensive, there's no value in caching it. -- Steven D'Aprano