3
\$\begingroup\$

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 _
\$\endgroup\$
6
  • \$\begingroup\$ 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. \$\endgroup\$
    – Dair
    Feb 11, 2016 at 9:51
  • \$\begingroup\$ @Dair It might not be available to everyone since lru_cache has only been added in Python 3.2. \$\endgroup\$ Feb 11, 2016 at 10:10
  • \$\begingroup\$ @MathiasEttinger: Good point. I still think he should be aware, especially since he hasn't specified his python version. \$\endgroup\$
    – Dair
    Feb 11, 2016 at 10:12
  • \$\begingroup\$ @Dair Yes, it's just that, by the look of things, he seems to be using Python 2. But your point remains valid anyway. \$\endgroup\$ Feb 11, 2016 at 10:20
  • \$\begingroup\$ 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. \$\endgroup\$
    – Eugene
    Feb 11, 2016 at 10:31

1 Answer 1

1
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ What you mean by explicit names for variables? \$\endgroup\$
    – Eugene
    Feb 11, 2016 at 10:35
  • \$\begingroup\$ @Eugene _ has no meaning; memoizer has an explicit name which convey meaning. \$\endgroup\$ Feb 11, 2016 at 10:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.