Is there a built-in Python cache decorator that can store function return values?

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.