-
-
Save chris-chris/c05228a25f1a3a9f296abc80d6019afd to your computer and use it in GitHub Desktop.
Decorator for using dicts/lists with any Python cache function (like lru_cache)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Inspired by https://gist.github.com/harel/9ced5ed51b97a084dec71b9595565a71 | |
from collections import namedtuple | |
import functools | |
import json | |
import six | |
Serialized = namedtuple('Serialized', 'json') | |
def hashable_cache(cache): | |
def hashable_cache_internal(func): | |
def deserialize(value): | |
if isinstance(value, Serialized): | |
return json.loads(value.json) | |
else: | |
return value | |
def func_with_serialized_params(*args, **kwargs): | |
_args = tuple([deserialize(arg) for arg in args]) | |
_kwargs = {k: deserialize(v) for k, v in six.viewitems(kwargs)} | |
return func(*_args, **_kwargs) | |
cached_func = cache(func_with_serialized_params) | |
@functools.wraps(func) | |
def hashable_cached_func(*args, **kwargs): | |
_args = tuple([ | |
Serialized(json.dumps(arg, sort_keys=True)) | |
if type(arg) in (list, dict) else arg | |
for arg in args | |
]) | |
_kwargs = { | |
k: Serialized(json.dumps(v, sort_keys=True)) | |
if type(v) in (list, dict) else v | |
for k, v in kwargs.items() | |
} | |
return cached_func(*_args, **_kwargs) | |
hashable_cached_func.cache_info = cached_func.cache_info | |
hashable_cached_func.cache_clear = cached_func.cache_clear | |
return hashable_cached_func | |
return hashable_cache_internal | |
# Example usage below | |
from cachetools.func import lru_cache | |
@hashable_cache(lru_cache()) | |
def fib(n): | |
assert n >= 0 | |
if n == 0: | |
return 0 | |
elif n == 1: | |
return 1 | |
else: | |
return fib(n - 1) + fib(n - 2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment