code: def memoized_property(func=None, key_factory=per_instance, **kwargs):
    
    getter = memoized_method(func=func, key_factory=key_factory, **kwargs)
    return property(fget=getter, fdel=lambda self: getter.forget(self))
docs: A convenience wrapper for memoizing properties.
  
    Applied like so:
  
    >>> class Foo(object):
    ...   @memoized_property
    ...   def name(self):
    ...     pass
  
    Is equivalent to:
  
    >>> class Foo(object):
    ...   @property
    ...   @memoized_method
    ...   def name(self):
    ...     pass
  
    Which is equivalent to:
  
    >>> class Foo(object):
    ...   @property
    ...   @memoized(key_factory=per_instance)
    ...   def name(self):
    ...     pass
  
    By default a deleter for the property is setup that un-caches the property such that a subsequent
    property access re-computes the value.  In other words, for this `now` @memoized_property:
  
    >>> import time
    >>> class Bar(object):
    ...   @memoized_property
    ...   def now(self):
    ...     return time.time()
  
    You could write code like so:
  
    >>> bar = Bar()
    >>> bar.now
    1433267312.622095
    >>> time.sleep(5)
    >>> bar.now
    1433267312.622095
    >>> del bar.now
    >>> bar.now
    1433267424.056189
    >>> time.sleep(5)
    >>> bar.now
    1433267424.056189
    >>>
  
    :API: public
  
    :param func: The property getter method to wrap.  Only generally passed by the python runtime and
                 should be omitted when passing a custom `key_factory` or `cache_factory`.
    :param key_factory: A function that can form a cache key from the arguments passed to the
                        wrapped, memoized function; by default `per_instance`.
    :param kwargs: Any extra keyword args accepted by `memoized`.
    :raises: `ValueError` if the wrapper is applied to anything other than a function.
    :returns: A read-only property that memoizes its calculated value and un-caches its value when
              `del`ed.