A cached property is a read-only property that is calculated on demand and automatically cached. If the value has already been calculated, the cached value is returned.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def cached_property(f):
"""returns a cached property that is calculated by function f"""
def get(self):
try:
return self._property_cache[f]
except AttributeError:
self._property_cache = {}
x = self._property_cache[f] = f(self)
return x
except KeyError:
x = self._property_cache[f] = f(self)
return x
return property(get)
|
Example:
class Swallow:
def __init__(self, laden):
self.mass = 5.0
self.laden = laden
def calc_air_speed_velocity(self):
coconut_mass = 16.0
t0 = time.time()
mass = self.mass + (coconut_mass if self.laden else 0.0)
distance = 43
time.sleep(mass*distance/1000.0) # must sleep after flying
t = time.time() - t0
return distance/t
air_speed_velocity = cached_property(calc_air_speed_velocity)
s1 = Swallow(False)
s2 = Swallow(True)
print s1.air_speed_velocity
print s2.air_speed_velocity
print s1.air_speed_velocity # notice that the second two invocations do not take any time.
print s2.air_speed_velocity
It works as a decorator.
This might be of interest:
Easy Property Creation in Python http://code.activestate.com/recipes/576742/
Only 7 lines of code, easy to understand, easy to use, easy to customize, save you a lot of typing
Thanks for writing this. Here's a slightly modified version using functools.wraps() which preserves the original property docstring and name:
Another modification/improvement: you can define member variable names, whose change should trigger the recalculation of the cached value.
Usage example: