Recently I have seen use of cached_properties decorators in some of the codebases of python 3rd party packages like celery and django (it's also a utility function in Django) and the bottle web framework. There also exists a standalone package for using cached_properties.
As far as I understand it's about avoiding heavy computations by providing caching behaviour.
Here is the source code stripped out that implements cached_property:
class cached_property(object):
"""
A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Deleting the attribute resets the property."""
def __init__(self, func):
self.__doc__ = getattr(func, '__doc__')
self.func = func
def __get__(self, obj, cls):
if obj is None:
return self
value = obj.__dict__[self.func.__name__] = self.func(obj)
return value
and this is how it is used:
class Monopoly(object):
def __init__(self):
self.boardwalk_price = 500
@cached_property
def boardwalk(self):
# Again, this is a silly example. Don't worry about it, this is
# just an example for clarity.
self.boardwalk_price += 50
return self.boardwalk_price
Now when we run it the price stays at $550.
>>> monopoly = Monopoly()
>>> monopoly.boardwalk
550
>>> monopoly.boardwalk
550
>>> monopoly.boardwalk
550
can't we simply store the result of first call to the attribute/property and use it later to avoid recomputation? I am sure this is a very silly question but what am I missing here?
ex:
monopoly = Monopoly()
>>> stored_value = monopoly.boardwalk
550
# now use stored_value instead of making a call to `monopoly.boardwalk`.