Python Cookbook

Author: Alex Martelli, Anna Ravenscroft, David Ascher
3.9
All Comments
TopTalkedBooks posted at August 20, 2017

What you are looking for is Denis Otkidach's excellent CachedAttribute:

class CachedAttribute(object):    
    '''Computes attribute value and caches it in the instance.
    From the Python Cookbook (Denis Otkidach)
    This decorator allows you to create a property which can be computed once and
    accessed many times. Sort of like memoization.
    '''
    def __init__(self, method, name=None):
        # record the unbound-method and the name
        self.method = method
        self.name = name or method.__name__
        self.__doc__ = method.__doc__
    def __get__(self, inst, cls):
        # self: <__main__.cache object at 0xb781340c>
        # inst: <__main__.Foo object at 0xb781348c>
        # cls: <class '__main__.Foo'>       
        if inst is None:
            # instance attribute accessed on class, return self
            # You get here if you write `Foo.bar`
            return self
        # compute, cache and return the instance's attribute value
        result = self.method(inst)
        # setattr redefines the instance's attribute so this doesn't get called again
        setattr(inst, self.name, result)
        return result

It can be used like this:

def demo_cache():
    class Foo(object):
        @CachedAttribute
        def bar(self):
            print 'Calculating self.bar'  
            return 42
    foo=Foo()
    print(foo.bar)
    # Calculating self.bar
    # 42

Notice that accessing foo.bar subsequent times does not call the getter function. (Calculating self.bar is not printed.)

    print(foo.bar)    
    # 42
    foo.bar=1
    print(foo.bar)
    # 1

Deleting foo.bar from foo.__dict__ re-exposes the property defined in Foo. Thus, calling foo.bar again recalculates the value again.

    del foo.bar
    print(foo.bar)
    # Calculating self.bar
    # 42

demo_cache()

The decorator was published in the Python Cookbook and can also be found on ActiveState.

This is efficient because although the property exists in the class's __dict__, after computation, an attribute of the same name is created in the instance's __dict__. Python's attribute lookup rules gives precedence to the attribute in the instance's __dict__, so the property in class becomes effectively overridden.

TopTalkedBooks posted at August 20, 2017

+1 for Dive into Python and Python in a Nutshell. I also highly recommend effbot's Guide to the Standard Library. You'll probably also want to check out the Python Cookbook for some good examples of idiomatic Python code. Check out Foundations of Python Networking to pick up where the SysAdmin book leaves off in terms of network protocols (fyi: all APress books are available as PDFs, which I love)

TopTalkedBooks posted at August 20, 2017

Have you read the Python Cookbook? It's a pretty good source for Pythonic.

Plus you'll find much more from Alex Martelli on Stack Overflow.

Top Books
We collected top books from hacker news, stack overflow, Reddit, which are recommended by amazing people.