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

 Download
Download Copy to clipboard
Copy to clipboard
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: