def cache_result(cache):

    def decorator(fun):

        def wrapper(*args, **kwargs):
            key = produce_cache_key(fun, *args, **kwargs)
if key not in cache:
    cache[key] = fun(*args, **kwargs)
return cache[key]
return wrapper
return decorator

@cache_result(cache_dict)
def fx(x, y, z=0):
    print('Doing some expensive job...')
cache = {}
fx(1, 2, z=1)
fx(1, 2, z=1)
Data structure of memoization in db