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:
1 2 3 4 5 6 7 8 9 10 11 | # 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:
1 | {% 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:
1 2 3 4 5 6 7 | 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:
1 2 3 | # in the view: if person.friends: ... |
The cached value can be treated like an ordinary attribute of the instance:
1 2 3 4 5 | # 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:
1 | 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:
1 2 3 4 | 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.