Python Functools – cached_property()

10 May, 2020
The @cached_property is a decorator which transforms a method of a class into a property whose value is computed only once and then cached as a normal attribute. Therefore, the cached result will be available as long as the instance will persist and we can use that method as an attribute of a class i.e
Writing    : instance.method
Instead of : instance.method()

cached_property is a part of functools module in Python. It is similar to property(), but cached_property() comes with an extra feature and that is caching.
Note: For more information, refer to Functools module in Python
The cache memory is a high-speed memory available inside CPU in order to speed up access to data and instructions. Therefore, the cache is a place that is quick to access. The result can be computed and stored once and from next time, the result can be accessed without recomputing it again. So, it is useful in case of expensive computations.
Difference between @property and @cached_property:
# Using @property  # A sample classclass Sample():      def __init__(self):      self.result = 50      @property    # a method to increase the value of    # result by 50    def increase(self):        self.result = self.result + 50        return self.result  # obj is an instance of the class sampleobj = Sample()print(obj.increase)print(obj.increase)print(obj.increase)
OUTPUT
100
150
200

Same code but now we use @cached_property instead of @property
# Using @cached_property  from functools import cached_property  # A sample classclass Sample():      def __init__(self):      self.result = 50      @cached_property    # a method to increase the value of    # result by 50    def increase(self):        self.result = self.result + 50        return self.result  # obj is an instance of the class sampleobj = Sample()print(obj.increase)print(obj.increase)print(obj.increase)
OUTPUT
100
100
100

You can clearly see that with @property the value of the result is computed each time the increase() method is called, that’s why it’s valued gets increased by 50. But with @cached_property, the value of the result is computed only once and then stored in the cache, so that it can be accessed each time the increase() method is called without recomputing the value of the result, and that’s why the output shows 100 every time.
But how does it reduces the execution time and makes the program faster ?Consider the following example:
# Without using @cached_property  # A sample classclass Sample():      def __init__(self, lst):      self.long_list = lst      # a method to find the sum of the     # given long list of integer values    def find_sum(self):        return (sum(self.long_list))  # obj is an instance of the class sample# the list can be longer, this is just# an exampleobj = Sample([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])print(obj.find_sum())print(obj.find_sum())print(obj.find_sum())
OUTPUT
55
55
55

Here, suppose if we pass a long list of values, the sum of the given list will be computed each time the find_sum() method is called, thereby taking much time for execution, and our program will ultimately become slow. What we want is that, since the list doesn’t change after the creation of the instance, so it would be nice, if the sum of the list is computed only once and not each time when we call the method and wish to access the sum. This can be achieved by using @cached_property
Example:
# With using @cached_property  from functools import cached_property  # A sample classclass Sample():    def __init__(self, lst):      self.long_list = lst      # a method to find the sum of the    # given long list of integer values    @cached_property    def find_sum(self):        return (sum(self.long_list))  # obj is an instance of the class sampleobj = Sample([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])print(obj.find_sum)print(obj.find_sum)print(obj.find_sum)
OUTPUT
55
55
55

Though the output is the same, it reduces the execution time a lot. The sum of the list that is passed at the time of the creation of the instance is computed only once and stored in the cache memory and thereafter, it uses the same, already calculated value of the sum each time we call find_sum() method and saves us form expensive recomputations of the sum. Thus it reduces the execution time and makes our program faster.
Python Decorators
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.