Skip to content

Instantly share code, notes, and snippets.

@jhorman
Created March 29, 2011 02:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhorman/891723 to your computer and use it in GitHub Desktop.
Save jhorman/891723 to your computer and use it in GitHub Desktop.
Decorator for caching return values in an LRU. Supports deferred results as well.
def cache(lifetime=None, cache_size=0):
""" Caching decorator. """
def attach_caching(method):
method._cache = pylru.lrucache(cache_size) if cache_size else {}
method._cache_updated = {}
@functools.wraps(method)
def wrapper(*args, **kw):
# frozenset is used to ensure hashability
key = args, frozenset(kw.iteritems()) if kw else args
# first check the cache for the value, and check the lifetime
if key in method._cache:
if not lifetime or (datetime.now()-method._cache_updated[key]) < lifetime:
return method._cache[key]
# call through
result = method(*args, **kw)
# caches the value on the method as long as not None
def cache(value):
if value:
method._cache[key] = value
method._cache_updated[key] = datetime.now()
return value
# if dealing with a twisted method, the caching is on the deferred result
if isinstance(result, Deferred):
result.addCallback(cache)
else:
# otherwise just cache
cache(result)
return result
return wrapper
return attach_caching
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment