Я использую вариант следующего декоратора для memoization (найдено здесь):
# 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
Мне интересно, есть ли разумный способ memoize на основе как args, так и kwargs, особенно в тех случаях, когда два вызова функций, заданные с аргументами, назначенными по-разному позиционно и через ключевое слово, но имеют те же самые аргументы?
