Text File
method.txt

Method Cache

cachedIn

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