I am trying to make a cache decorator for functions with numpy array input parameters
from functools import lru_cache
import numpy as np
from time import sleep
a = np.array([1,2,3,4])
@lru_cache()
def square(array):
sleep(1)
return array * array
square(a)
But numpy arrays are not hashable,
TypeError Traceback (most recent call last)
<ipython-input-13-559f69d0dec3> in <module>()
----> 1 square(a)
TypeError: unhashable type: 'numpy.ndarray'
So they need to be converted to tuples. I have this working and caching correctly:
@lru_cache()
def square(array_hashable):
sleep(1)
array = np.array(array_hashable)
return array * array
square(tuple(a))
But I wanted to wrap it all up in a decorator, so far I have tried:
def np_cache(function):
def outter(array):
array_hashable = tuple(array)
@lru_cache()
def inner(array_hashable_inner):
array_inner = np.array(array_hashable_inner)
return function(array_inner)
return inner(array_hashable)
return outter
@np_cache
def square(array):
sleep(1)
return array * array
But caching is not working. Computation is performed but not cached properly, as I am always waiting 1 second.
What am I missing here? I'm guessing lru_cache isn't getting the context right and its being instantiated in each call, but I don't know how to fix it.
I have tried blindly throwing the functools.wraps decorator here and there with no luck.