Skip to content

Instantly share code, notes, and snippets.

@sharoonthomas
Created January 25, 2012 01:02
Show Gist options
  • Save sharoonthomas/1673907 to your computer and use it in GitHub Desktop.
Save sharoonthomas/1673907 to your computer and use it in GitHub Desktop.
Python cached property implementation
class cached_property(object):
"""A decorator that converts a function into a lazy property. The
function wrapped is called the first time to retrieve the result
and then that calculated result is used the next time you access
the value::
class Foo(object):
@cached_property
def foo(self):
# calculate something important here
return 42
The class has to have a `__dict__` in order for this property to
work.
:copyright: (c) 2011 by the Werkzeug Team
:license: BSD
"""
# implementation detail: this property is implemented as non-data
# descriptor. non-data descriptors are only invoked if there is
# no entry with the same name in the instance's __dict__.
# this allows us to completely get rid of the access function call
# overhead. If one choses to invoke __get__ by hand the property
# will still work as expected because the lookup logic is replicated
# in __get__ for manual invocation.
def __init__(self, func, name=None, doc=None):
self.__name__ = name or func.__name__
self.__module__ = func.__module__
self.__doc__ = doc or func.__doc__
self.func = func
def __get__(self, obj, type=None):
if obj is None:
return self
value = obj.__dict__.get(self.__name__, _missing)
if value is _missing:
value = self.func(obj)
obj.__dict__[self.__name__] = value
return value
@schlamar
Copy link

schlamar commented Jul 5, 2013

This example is missing the _missing object :)

@tb69wn6127
Copy link

why need _missing value?

@Didericis
Copy link

@tb69wn6127 if the result is not in the dictionary, then the _missing value will be used. This value must be something that is never expected to be returned from the wrapped function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment