Source code for bag.memoize

"""Decorator for caching computed values."""

from functools import wraps
# Instead of wrapper.__doc__ = f.__doc__ and wrapper.__name__ = f.__name__,
# use functools.wraps.

[docs]def memoize(limit=None, keymaker=None, cache_type=dict, debug=False): """Memoize decorator with an LRU cache. When full, the cache discards the least recently used value. You can pass cache_type=WeakValueDictionary (not tested). """ if not keymaker: try: from cPickle import dumps except ImportError: from pickle import dumps keymaker = lambda *a, **kw: dumps((a, kw)) def decoratr(fn): cache = cache_type() popular = [] @wraps(fn) def wrapper(*a, **kw): key = keymaker(*a, **kw) try: popular.append(popular.pop(popular.index(key))) except ValueError: cache[key] = fn(*a, **kw) popular.append(key) if limit is not None and len(popular) > limit: del cache[popular.pop(0)] else: if debug: print('Hit cache of {0}(). Value:\n {1}'.format( fn.__name__, key)) return cache[key] wrapper.cache = cache wrapper.popular = popular wrapper.limit = limit wrapper.func = fn return wrapper return decoratr
if __name__ == "__main__": # Example usage # Will cache up to 100 items, dropping the least recently used if # the limit is exceeded. @memoize(100) def fibo(n): if n > 1: return fibo(n - 1) + fibo(n - 2) else: return n print(fibo(100)) # Same as above, but with no limit on cache size @memoize() def fibonl(n): if n > 1: return fibo(n - 1) + fibo(n - 2) else: return n print(fibonl(100))