pythoncachingdecoratormemoization

Is there a decorator to simply cache 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, but I think the caching could be factored out into a decorator. Only I didn't find one like it ;)

PS the real calculation doesn't depend on mutable values


Solution

  • Python 3.8 functools.cached_property decorator

    https://docs.python.org/dev/library/functools.html#functools.cached_property

    cached_property from Werkzeug was mentioned at: https://stackoverflow.com/a/5295190/895245 but a supposedly derived version will be merged into 3.8, which is awesome.

    This decorator can be seen as caching @property, or as a cleaner @functools.lru_cache for when you don't have any arguments.

    The docs say:

    @functools.cached_property(func)
    

    Transform a method of a class into a property whose value is computed once and then cached as a normal attribute for the life of the instance. Similar to property(), with the addition of caching. Useful for expensive computed properties of instances that are otherwise effectively immutable.

    Example:

    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)
    

    New in version 3.8.

    Note This decorator requires that the dict attribute on each instance be a mutable mapping. This means it will not work with some types, such as metaclasses (since the dict attributes on type instances are read-only proxies for the class namespace), and those that specify slots without including dict as one of the defined slots (as such classes don’t provide a dict attribute at all).