Class method decorator that creates a property that returns the protected attribute
    or the value returned by the wrapped method, if the protected attribute is not defined.

def protected_property(func):
    """
    Class method decorator that creates a property that returns the protected attribute
    or the value returned by the wrapped method, if the protected attribute is not defined.
    """
    if func.__name__.startswith('_'):
        raise ValueError("%r: Cannot decorate a protected method!" % func)

    @property
    @wraps(func)
    def proxy_wrapper(self):
        try:
            return getattr(self, '_%s' % func.__name__)
        except AttributeError:
            pass
        return func(self)

    return proxy_wrapper