code: def cached_property(self, key_fn=_key_fn, timeout=None):
          
          this = self
  
          class _cached_property(object):
              def __init__(self, fn):
                  self._fn = this.cached(key_fn, timeout)(fn)
  
              def __get__(self, instance, instance_type=None):
                  if instance is None:
                      return self
                  return self._fn(instance)
  
              def __delete__(self, obj):
                  self._fn.bust(obj)
  
              def __set__(self, instance, value):
                  raise ValueError('Cannot set value of a cached property.')
  
          def decorator(fn):
              return _cached_property(fn)
  
          return decorator
docs: Decorator that will transparently cache calls to the wrapped
          method. The method will be exposed as a property.
  
          Usage::
  
              cache = Cache(my_database)
  
              class Clock(object):
                  @cache.cached_property()
                  def now(self):
                      return datetime.datetime.now()
  
              clock = Clock()
              print clock.now