How to use lru_cache for static method and with unhashable arguments like lists in python
I have tried using methodtools lru_cache method. It gives an error that call is not working.
How to use lru_cache for static method and with unhashable arguments like lists in python
I have tried using methodtools lru_cache method. It gives an error that call is not working.
You could use a separate decorator to sanitize the inputs. Something like this:
def sanitize_args(*expected_types):
def make_decorator(decorated):
@functools.wraps(decorated)
def decorator(*args):
if len(args) != len(expected_types):
raise TypeError("Wrong number of arguments")
args = (type_(arg) for type_, arg in zip(expected_types, args))
return decorated(*args)
return decorator
return make_decorator
class Foo:
@staticmethod
@sanitize_args(tuple, str)
@functools.lru_cache
def bar(sequence, label):
return (label, sum(sequence))
print(Foo.bar([1, 2, 3], "foo"))
However, getting this right (and fast) in a generic fashion is a bit tedious. Note how I left out keyword arguments for simplicity.
An easier solution is to use an uncached public interface with an lru-cached private implementation. Something like this:
class Foo:
@staticmethod
@functools.lru_cache
def _implement_bar(sequence, label):
return (label, sum(sequence))
@staticmethod
def bar(sequence, label):
return Foo._implement_bar(tuple(sequence), str(label))