def lazy_property(func):
attr_name = '<STR_LIT>' + func.__name__<EOL>@property<EOL>def _lazy_property(self):<EOL><INDENT>if not hasattr(self, attr_name):<EOL><INDENT>setattr(self, attr_name, func(self))<EOL><DEDENT>return getattr(self, attr_name)<EOL><DEDENT>@_lazy_property.deleter<EOL>def _lazy_property(self):<EOL><INDENT>if hasattr(self, attr_name):<EOL><INDENT>delattr(self, attr_name)<EOL><DEDENT><DEDENT>@_lazy_property.setter<EOL>def _lazy_property(self, value):<EOL><INDENT>setattr(self, attr_name, value)<EOL><DEDENT>return _lazy_property<EOL>
Wraps a property to provide lazy evaluation. Eliminates boilerplate.
Also provides for setting and deleting the property.

Use as you would use the @property decorator::

    # OLD:
    class MyClass():
        def __init__():
            self._compute = None

        @property
        def compute(self):
            if self._compute is None:
                # computationally intense stuff
                # ...
                # ...
                self._compute = result
            return self._compute

        @compute.setter
        def compute(self, value):
            self._compute = value


    # NEW:
    class MyClass():

        def __init__():
            pass

        @lazy_property
        def compute(self):
            # computationally intense stuff
            # ...
            # ...
            return result

.. note:

    Properties wrapped with ``lazy_property`` are only evaluated once.
    If the instance state changes, lazy properties will not be automatically
    re-evaulated and the update must be explicitly called for::

        c = MyClass(data)
        prop = c.lazy_property

        # If you update some data that affects c.lazy_property
        c.data = new_data

        # c.lazy_property won't change
        prop == c.lazy_property  # TRUE

        # If you want to update c.lazy_property, you can delete it, which will
        # force it to be recomputed (with the new data) the next time you use it
        del c.lazy_property
        new_prop = c.lazy_property
        new_prop == prop  # FALSE