Tests of the ``cached_property`` function, which computes
the property value on first access and stores it in the
instance dict, so subsequent accesses are just simple
attribute references.

    >>> from plib.stdlib import cached_property
    >>> class Test(object):
    ...     def test(self):
    ...         print "Doing initial calculation..."
    ...         return "Test done."
    ...     test = cached_property(test)
    ... 
    >>> t = Test()
    >>> 'test' in t.__dict__
    False
    >>> print t.test
    Doing initial calculation...
    Test done.
    >>> 'test' in t.__dict__
    True
    >>> print t.test
    Test done.

The cached value can be explicitly deleted from the instance
dict, or overwritten by an explicit assignment to the
attribute. Deletion "resets" the property, so it has to be
computed again on the next access.

    >>> del t.test
    >>> 'test' in t.__dict__
    False
    >>> t.test = "Other value."
    >>> print t.test
    Other value.
    >>> del t.test
    >>> print t.test
    Doing initial calculation...
    Test done.

One other wrinkle: ``hasattr`` also triggers the property
computation.

    >>> del t.test
    >>> hasattr(t, 'test')
    Doing initial calculation...
    True
    >>> 'test' in t.__dict__
    True
    >>> print t.test
    Test done.
