Skip to content

Instantly share code, notes, and snippets.

@bofm
Last active August 5, 2016 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bofm/dbc04a014ca5fb25414f96ae208f03e6 to your computer and use it in GitHub Desktop.
Save bofm/dbc04a014ca5fb25414f96ae208f03e6 to your computer and use it in GitHub Desktop.
Python lru_cache-like decorator which supports mutable args
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