class cached_property(object, name)
[source]
The @cached_property
decorator caches the result of a method with a single self
argument as a property. The cached result will persist as long as the instance does, so if the instance is passed around and the function subsequently invoked, the cached result will be returned.
Consider a typical case, where a view might need to call a model’s method to perform some computation, before placing the model instance into the context, where the template might invoke the method once more:
# the model class Person(models.Model): def friends(self): # expensive computation ... return friends # in the view: if person.friends(): ...
And in the template you would have:
{% for friend in person.friends %}
Here, friends()
will be called twice. Since the instance person
in the view and the template are the same, @cached_property
can avoid that:
from django.utils.functional import cached_property @cached_property def friends(self): # expensive computation ... return friends
Note that as the method is now a property, in Python code it will need to be invoked appropriately:
# in the view: if person.friends: ...
The cached value can be treated like an ordinary attribute of the instance:
# clear it, requiring re-computation next time it's called del person.friends # or delattr(person, "friends") # set a value manually, that will persist on the instance until cleared person.friends = ["Huckleberry Finn", "Tom Sawyer"]
As well as offering potential performance advantages, @cached_property
can ensure that an attribute’s value does not change unexpectedly over the life of an instance. This could occur with a method whose computation is based on datetime.now()
, or simply if a change were saved to the database by some other process in the brief interval between subsequent invocations of a method on the same instance.
You can use the name
argument to make cached properties of other methods. For example, if you had an expensive get_friends()
method and wanted to allow calling it without retrieving the cached value, you could write:
friends = cached_property(get_friends, name='friends')
While person.get_friends()
will recompute the friends on each call, the value of the cached property will persist until you delete it as described above:
x = person.friends # calls first time y = person.get_friends() # calls again z = person.friends # does not call x is z # is True
Please login to continue.