Last active
August 5, 2016 11:16
-
-
Save bofm/dbc04a014ca5fb25414f96ae208f03e6 to your computer and use it in GitHub Desktop.
Python lru_cache-like decorator which supports mutable args
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
import typing | |
from collections import OrderedDict | |
def lru_cache2(size=128): | |
cache = OrderedDict() | |
def make_key(x): | |
if isinstance(x, typing.Mapping): | |
return (id(type(x)), *((k, make_key(v)) for k, v in sorted(x.items()))) | |
elif isinstance(x, typing.Set): | |
return (id(type(x)), *map(make_key, sorted(x))) | |
elif isinstance(x, typing.Sequence): | |
return (id(type(x)), *map(make_key, x)) | |
else: | |
try: | |
hash(x) | |
except TypeError: | |
return id(type(x)), str(x) | |
else: | |
return id(type(x)), x | |
def decorator(fn): | |
@wraps(fn) | |
def wrapped(*args, **kwargs): | |
key = make_key((id(fn), args, kwargs)) | |
try: | |
return cache[key] | |
except KeyError: | |
res = fn(*args, **kwargs) | |
cache[key] = res | |
while len(cache) >= size: | |
cache.pop(last=False) | |
return res | |
return wrapped | |
return decorator |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment