def lazyproperty(method):
    """Decorator for methods defining an attribute's one-time evaluation.

    Once the attribute's value has been evaluated (i.e. after it is called
    for the first time), this value is returned without further evaluation
    at each new call.

    It is however possible to delete the value using `del`, so that it is
    re-evaluated on the next call (but not on the following ones).

    Example:
    >>> class Foo:
    ...     def __init__(self, x):
    ...         self.x = x
    ...     @lazyproperty
    ...     def bar(self):
    ...         return self.x
    ...
    >>> foo = Foo(0)
    >>> foo.bar
    0
    >>> foo.x = 1
    >>> foo.bar
    0
    >>> del foo.bar
    >>> foo.bar
    1
    """
    name = method.__name__
    def getter(instance, *args, **kwargs):
        """Return the property's value, evaluating it if needed."""
        if name not in instance.__dict__.keys():
            instance.__dict__[name] = method(instance, *args, **kwargs)
        return instance.__dict__[name]
    def deleter(instance):
        """Delete the property's value."""
        instance.__dict__.pop(name, None)
    doc = getattr(method, '__doc__', None)
    if doc is None:
        doc = 'Lazy property %s.' % method.__name__
    return property(getter, fdel=deleter, doc=doc)