import functools


def memoize_to_attribute(attr_name, _test=False):
    """
    Decorate a method and cache return values in attr_name of the parent object.
    Used to speed up some often called methods that cache their values in
    instance variables.
    Usage example::

    >>> class Obj(object):
    ...     def __init__(self):
    ...         self._expensive = None
    ...     @property
    ...     @memoize_to_attribute('_expensive')
    ...     def expensive(self):
    ...         print('Calling expensive')
    ...         return 'value expensive to compute'
    >>> o=Obj()
    >>> o.expensive
    Calling expensive
    'value expensive to compute'
    >>> o.expensive
    'value expensive to compute'
    >>> o.expensive
    'value expensive to compute'

    The Obj().expensive property value will be cached to attr_name
    self._expensive and computed only once in the life of the Obj instance.
    """
    def memoized_to_attr(meth):
        @functools.wraps(meth)
        def wrapper(self, *args, **kwargs):
            if getattr(self, attr_name) is None:
                res = meth(self, *args, **kwargs)
                setattr(self, attr_name, res)
            else:
                res = getattr(self, attr_name)
            return res
        return wrapper

    return memoized_to_attr