The cachedIn property allows to specify the attribute where to store the computed value:
>>> import math >>> from zope.cachedescriptors import method>>> class Point(object): ... ... def __init__(self, x, y): ... self.x, self.y = x, y ... ... @method.cachedIn('_cache') ... def distance(self, x, y): ... print 'computing distance' ... return math.sqrt((self.x - x)**2 + (self.y - y)**2) ... >>> point = Point(1.0, 2.0)
The value is computed once:
>>> point.distance(2, 2) computing distance 1.0 >>> point.distance(2, 2) 1.0
Using different arguments calculates a new distance:
>>> point.distance(5, 2) computing distance 4.0 >>> point.distance(5, 2) 4.0
The data is stored at the given _cache attribute:
>>> isinstance(point._cache, dict) True>>> sorted(point._cache.items()) [(((2, 2), ()), 1.0), (((5, 2), ()), 4.0)]
It is possible to exlicitly invalidate the data:
>>> point.distance.invalidate(point, 5, 2) >>> point.distance(5, 2) computing distance 4.0
Invalidating keys which are not in the cache, does not result in an error:
>>> point.distance.invalidate(point, 47, 11)
It is possible to pass in a factory for the cache attribute. Create another Point class:
>>> class MyDict(dict): ... pass >>> class Point(object): ... ... def __init__(self, x, y): ... self.x, self.y = x, y ... ... @method.cachedIn('_cache', MyDict) ... def distance(self, x, y): ... print 'computing distance' ... return math.sqrt((self.x - x)**2 + (self.y - y)**2) ... >>> point = Point(1.0, 2.0) >>> point.distance(2, 2) computing distance 1.0
Now the cache is a MyDict instance:
>>> isinstance(point._cache, MyDict) True