# caching decorator

I came up with a caching decorator for pure functions. Is it ok? Could it be better/simpler/faster?

def cached(f):
def _(*args):
if args in _._cache:
return _._cache[args]
else:
result = f(*args)
_._cache[args] = result
return result
_._cache = {}
return _

• I mean, not an improvement or anything, but they do have a lru_cache function already built into the library. I would suspect it to be faster than this... In other words, if this is part of a bigger scheme I would consider using lru_cache instead. – Dair Feb 11 '16 at 9:51
• @Dair It might not be available to everyone since lru_cache has only been added in Python 3.2. – 409_Conflict Feb 11 '16 at 10:10
• @MathiasEttinger: Good point. I still think he should be aware, especially since he hasn't specified his python version. – Dair Feb 11 '16 at 10:12
• @Dair Yes, it's just that, by the look of things, he seems to be using Python 2. But your point remains valid anyway. – 409_Conflict Feb 11 '16 at 10:20
• I'm using Python 2.6 and LRU cache as I understand it stores only a limited set of latest used results and I need a full cache. – Eugene Feb 11 '16 at 10:31

What you are trying to achieve is called memoization and has already a number of recipe available on the Python wiki.

Your implementation matches the one using nested functions:

# note that this decorator ignores **kwargs
def memoize(obj):
cache = obj.cache = {}

@functools.wraps(obj)
def memoizer(*args, **kwargs):
if args not in cache:
cache[args] = obj(*args, **kwargs)
return cache[args]
return memoizer


A few things to note here on top of yours:

• usage of a local variable which resolves faster than an attribute lookup
• usage of functools.wraps which keeps some properties of the original function intact (name and docstring, mainly)
• explicit names for variables
• What you mean by explicit names for variables? – Eugene Feb 11 '16 at 10:35
• @Eugene _ has no meaning; memoizer has an explicit name which convey meaning. – 409_Conflict Feb 11 '16 at 10:37