from functools import lru_cache
def hashifying_lru_cache(
func_or_None=None, maxsize=128, typed=False, hasher=id):
def decorator(func):
class Hashified:
def __init__(self, obj):
self.obj = obj
def __eq__(self, other):
return hasher(self.obj) == hasher(other.obj)
def __hash__(self):
return hasher(self.obj)
def unwrapper(*args, **kwargs):
return func(
*(arg.obj if isinstance(arg, Hashified) else arg
for arg in args),
**{name: value.obj if isinstance(value, Hashified) else value
for name, value in kwargs.items()}
)
def wrapper(*args, **kwargs):
return decorated(
*(Hashified(arg) if arg.__hash__ is None else arg
for arg in args),
**{name: Hashified(value) if value.__hash__ is None else value
for name, value in kwargs.items()}
)
decorated = lru_cache(maxsize=maxsize, typed=typed)(unwrapper)
return wrapper
return decorator if func_or_None is None else decorator(func_or_None)
@hashifying_lru_cache
def sum_list(const_list):
print('got', const_list)
return sum(const_list)
lst = [1, 2, 3]
print(sum_list(lst))
print(sum_list(lst))
ZnJvbSBmdW5jdG9vbHMgaW1wb3J0IGxydV9jYWNoZQoKZGVmIGhhc2hpZnlpbmdfbHJ1X2NhY2hlKAogICAgICAgIGZ1bmNfb3JfTm9uZT1Ob25lLCBtYXhzaXplPTEyOCwgdHlwZWQ9RmFsc2UsIGhhc2hlcj1pZCk6CiAgICBkZWYgZGVjb3JhdG9yKGZ1bmMpOgogICAgICAgIGNsYXNzIEhhc2hpZmllZDoKICAgICAgICAgICAgZGVmIF9faW5pdF9fKHNlbGYsIG9iaik6CiAgICAgICAgICAgICAgICBzZWxmLm9iaiA9IG9iagogICAgICAgICAgICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKICAgICAgICAgICAgICAgIHJldHVybiBoYXNoZXIoc2VsZi5vYmopID09IGhhc2hlcihvdGhlci5vYmopCiAgICAgICAgICAgIGRlZiBfX2hhc2hfXyhzZWxmKToKICAgICAgICAgICAgICAgIHJldHVybiBoYXNoZXIoc2VsZi5vYmopCiAgICAgICAgZGVmIHVud3JhcHBlcigqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICByZXR1cm4gZnVuYygKICAgICAgICAgICAgICAgICooYXJnLm9iaiBpZiBpc2luc3RhbmNlKGFyZywgSGFzaGlmaWVkKSBlbHNlIGFyZwogICAgICAgICAgICAgICAgICAgIGZvciBhcmcgaW4gYXJncyksCiAgICAgICAgICAgICAgICAqKntuYW1lOiB2YWx1ZS5vYmogaWYgaXNpbnN0YW5jZSh2YWx1ZSwgSGFzaGlmaWVkKSBlbHNlIHZhbHVlCiAgICAgICAgICAgICAgICAgICAgZm9yIG5hbWUsIHZhbHVlIGluIGt3YXJncy5pdGVtcygpfQogICAgICAgICAgICApCiAgICAgICAgZGVmIHdyYXBwZXIoKmFyZ3MsICoqa3dhcmdzKToKICAgICAgICAgICAgcmV0dXJuIGRlY29yYXRlZCgKICAgICAgICAgICAgICAgICooSGFzaGlmaWVkKGFyZykgaWYgYXJnLl9faGFzaF9fIGlzIE5vbmUgZWxzZSBhcmcKICAgICAgICAgICAgICAgICAgICBmb3IgYXJnIGluIGFyZ3MpLAogICAgICAgICAgICAgICAgKip7bmFtZTogSGFzaGlmaWVkKHZhbHVlKSBpZiB2YWx1ZS5fX2hhc2hfXyBpcyBOb25lIGVsc2UgdmFsdWUKICAgICAgICAgICAgICAgICAgICBmb3IgbmFtZSwgdmFsdWUgaW4ga3dhcmdzLml0ZW1zKCl9CiAgICAgICAgICAgICkKICAgICAgICBkZWNvcmF0ZWQgPSBscnVfY2FjaGUobWF4c2l6ZT1tYXhzaXplLCB0eXBlZD10eXBlZCkodW53cmFwcGVyKQogICAgICAgIHJldHVybiB3cmFwcGVyCiAgICByZXR1cm4gZGVjb3JhdG9yIGlmIGZ1bmNfb3JfTm9uZSBpcyBOb25lIGVsc2UgZGVjb3JhdG9yKGZ1bmNfb3JfTm9uZSkKCkBoYXNoaWZ5aW5nX2xydV9jYWNoZQpkZWYgc3VtX2xpc3QoY29uc3RfbGlzdCk6CiAgICBwcmludCgnZ290JywgY29uc3RfbGlzdCkKICAgIHJldHVybiBzdW0oY29uc3RfbGlzdCkKCmxzdCA9IFsxLCAyLCAzXQpwcmludChzdW1fbGlzdChsc3QpKQpwcmludChzdW1fbGlzdChsc3QpKQ==