Cache descriptors for Python and Zope
Project description
gocept.cache
Method cache
Memoize with timeout
Memoize with timeout caches methods with a certain timeout:
>>> import math >>> import gocept.cache.method >>> >>> class Point(object): ... ... def __init__(self, x, y): ... self.x, self.y = x, y ... ... @gocept.cache.method.Memoize(0.1) ... def distance(self, x, y): ... print 'computing distance' ... return math.sqrt((self.x - x)**2 + (self.y - y)**2) ... ... @gocept.cache.method.Memoize(0.1, ignore_self=True) ... def add_one(self, i): ... if not isinstance(i, int): ... print "I want an int" ... else: ... print 'adding one' ... return i + 1 ... >>> point = Point(1.0, 2.0)
When we first ask for the distance it is computed:
>>> point.distance(2, 2) computing distance 1.0
The second time the distance is not computed but returned from the cache:
>>> point.distance(2, 2) 1.0
Now, let’s wait 0.1 secondes, the value we set as cache timeout. After that the distance is computed again:
>>> import time >>> time.sleep(0.5) >>> point.distance(2, 2) computing distance 1.0
When we create a new instance, the new instance gets its own cache:
>>> p2 = Point(1.0, 2.0) >>> p2.distance(2, 2) computing distance 1.0
It’s also possible to explicitly ignore self. We did this for the add_one method:
>>> point.add_one(3) adding one 4
The second time it’s not computed as you would expect: >>> point.add_one(3) 4
If we ask p2 now the result is not computed as well:
>>> p2.add_one(3) 4
If we put a non hashable argument into a memoized function it will not be cached:
>>> point.add_one({'a': 1}) I want an int >>> point.add_one({'a': 1}) I want an int
The decorated method can be introspected and yields the same results ad the original:
>>> import inspect >>> Point.distance.func_name 'distance' >>> inspect.getargspec(Point.distance) (['self', 'x', 'y'], None, None, None)
Store memoizations on an attribute
If you want more control over the cache used by gocept.cache.method.Memoize (e. g. you want to associate it with a gocept.cache.property.CacheDataManager to invalidate it on transaction boundaries), you can use the @memoize_on_attribute decorator to retrieve the cache-dictionary from the instance:
>>> class Bar(object): ... cache = {} ... ... @gocept.cache.method.memoize_on_attribute('cache', 10) ... def echo(self, x): ... print 'miss' ... return x
>>> bar = Bar() >>> bar.echo(5) miss 5 >>> bar.echo(5) 5 >>> bar.cache.clear() >>> bar.echo(5) miss 5
This decorator should be used on methods, not on plain functions, since it must be able to retrieve the cache-dictionary from the first argument of the function (which is ‘self’ for methods):
>>> @gocept.cache.method.memoize_on_attribute('cache', 10) ... def bar(): ... print 'foo' >>> bar() Traceback (most recent call last): TypeError: gocept.cache.method.memoize_on_attribute could not retrieve cache attribute 'cache' for function <function bar at 0x...>
>>> @gocept.cache.method.memoize_on_attribute('cache', 10) ... def baz(x): ... print 'foo' >>> baz(5) Traceback (most recent call last): TypeError: gocept.cache.method.memoize_on_attribute could not retrieve cache attribute 'cache' for function <function baz at 0x...>
Cached Properties
Transaction Bound Cache
The transaction bound cache is invalidated on transaction boundaries.
Create a class and set some data:
>>> import gocept.cache.property >>> class Foo(object): ... ... cache = gocept.cache.property.TransactionBoundCache('_cache', dict) ... >>> foo = Foo() >>> foo.cache {} >>> foo.cache['A'] = 1 >>> foo.cache {'A': 1}
If we commit the transaction the cache is empty again:
>>> import transaction >>> transaction.commit() >>> foo.cache {}
The same happens on abort:
>>> foo.cache['A'] = 1 >>> foo.cache {'A': 1} >>> transaction.abort() >>> foo.cache {}
Changes
0.4 (2009-06-18)
Registered clearing the cache with zope.testing.cleanup.
0.3 (2008-12-19)
Added @memoize_on_attribute to retrieve the memoization cache from the instance instead of using gocept.cache.method’s built-in cache.
0.2.2 (2007-12-17)
Fixed the bug in TransactionBoundCache where the cache was not invalidated on transaction abort.
0.2.1 (2007-10-17)
Fixed a bug in TransactionBoundCache which yielded an error in the log: TypeError: <lambda>() takes exactly 1 argument (2 given)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.