How to memoize/cache property access?

Duncan Booth duncan.booth at invalid.invalid
Thu Dec 20 11:18:15 EST 2007


thebjorn <BjornSteinarFjeldPettersen at gmail.com> wrote:

> It would have been nice to be able to write
> 
> class Foo(object):
>     @property
>     def expensive(self):
>         self.expensive = <insert expensive db call here>
>         return self.expensive
> 
> but apparently I "can't set [that] attribute" :-(

You can set and access it directly in __dict__. How about something along 
these lines:

def cachedproperty(f):
    name = f.__name__
    def getter(self):
        try:
            return self.__dict__[name]
        except KeyError:
            res = self.__dict__[name] = f(self)
            return res
    return property(getter)

class Foo(object):
    @cachedproperty
    def expensive(self):
        print "expensive called"
        return 42

>>> f = Foo()
>>> f.expensive
expensive called
42
>>> f.expensive
42

It is still calling the getter every time though, so not as fast as a plain 
attribute lookup.



More information about the Python-list mailing list