I've just written a simple caching / memoization python decorator. It's purpose is to cache what the function returns for all the arguments combinations it's been ever invoked with.
So, if, say, we had a function my_function(a, b=2, c=3)
invoked once with my_function(1, 2, c=3)
, the results should be then cached whenever I call it with my_function(1, 2, 3)
or my_function(1, c=3, b=2)
or my_function(c=3, b=2, a=1)
.
Is what's below a good approach and could it be somehow improved?
import functools
import pickle
def memoize_all(func):
"""
This is a caching decorator. It caches the function results for
all the arguments combinations, so use it with care. It does not matter whether the arguments
are passed as keywords or not.
"""
cache = {}
@functools.wraps(func)
def cached(*args, **kwargs):
arg_names = func.func_code.co_varnames
arg_dict = {}
for i, arg in enumerate(args):
arg_dict[arg_names[i]] = args[i]
arg_dict.update(**kwargs)
key = pickle.dumps(arg_dict)
if key not in cache:
cache[key] = func(*args, **kwargs)
return cache[key]
return cached
lru_cache
does this, and this SO question lists some 2.7 alternatives / backports \$\endgroup\$ – Tobias Kienzler Mar 16 '15 at 13:01