You need to ensure that each method gets cached independently while considering its dependencies. My solution? Modify the cache key to also include the method name of the previously computed step. Here is an example:
def cache(method):
def wrapper(self, *args):
if not hasattr(self, "_method_cache"):
self._method_cache = {}
# Include relevant instance variables + previous method's output
state_key = (self.min_val, self.max_val)
cache_key = (method.__name__, args, state_key, self._last_method)
if cache_key in self._method_cache:
return self._method_cache[cache_key]
result = method(self, *args)
self._method_cache[cache_key] = result
self._last_method = method.__name__ # Track last method called
return result
return wrapper