Is there a built-in Python cache decorator that can store function return values?
Consider the following:
@property
def name(self):
if not hasattr(self, '_name'):
# expensive calculation
self._name = 1 + 1
return self._name
I’m new to this, but I feel like the caching logic could be refactored into a decorator. However, I couldn’t find a suitable Python cache decorator.
PS: The real calculation doesn’t depend on mutable values.
A great solution for caching function return values in Python is the functools.cached_property decorator, introduced in Python 3.8.
This Python cache decorator works similarly to @property, but it caches the result after the first computation, making it useful for expensive calculations in otherwise immutable instances.
Here’s an example:
from functools import cached_property
import statistics
class DataSet:
def __init__(self, sequence_of_numbers):
self._data = sequence_of_numbers
@cached_property
def stdev(self):
return statistics.stdev(self._data)
@cached_property
def variance(self):
return statistics.variance(self._data)
This decorator effectively caches computed values and avoids redundant calculations.
If your method doesn’t rely on instance attributes, functools.lru_cache can be a great alternative:
from functools import lru_cache
class MathOps:
@lru_cache(maxsize=None)
def fibonacci(self, n):
if n < 2:
return n
return self.fibonacci(n - 1) + self.fibonacci(n - 2)
This caches function calls based on arguments, making it suitable for recursive calculations.
If you need more control, you can create a custom Python cache decorator:
def cached_property(func):
attr_name = f""_{func.__name__}""
@property
def wrapper(self):
if not hasattr(self, attr_name):
setattr(self, attr_name, func(self))
return getattr(self, attr_name)
return wrapper
class Example:
@cached_property
def expensive_computation(self):
print(""Computing value..."")
return 42 # Simulate an expensive operation
This decorator stores the computed value as an instance attribute, preventing redundant computations.