1 # -*- coding: utf-8 -*-
3 __author__
= 'Daniel Greenfeld'
4 __email__
= 'pydanny@gmail.com'
11 class cached_property(object):
12 """ A property that is only computed once per instance and then replaces
13 itself with an ordinary attribute. Deleting the attribute resets the
16 Source: https://github.com/bottlepy/bottle/commit/fa7733e075da0d790d809aa3d2f53071897e6f76
19 def __init__(self
, func
):
20 self
.__doc
__ = getattr(func
, '__doc__')
23 def __get__(self
, obj
, cls
):
26 value
= obj
.__dict
__[self
.func
.__name
__] = self
.func(obj
)
30 class timed_cached_property(object):
31 '''Decorator for read-only properties evaluated only once within TTL period.
33 It can be used to created a cached property like this::
37 # the class containing the property must be a new-style class
38 class MyClass(object):
39 # create property whose value is cached for ten minutes
40 @cached_property(ttl=600)
42 # will only be evaluated every 10 min. at maximum.
43 return random.randint(0, 100)
45 The value is cached in the '_cache' attribute of the object instance that
46 has the property getter method wrapped by this decorator. The '_cache'
47 attribute value is a dictionary which has a key for every property of the
48 object which is wrapped by this decorator. Each entry in the cache is
49 created only when the property is accessed for the first time and is a
50 two-element tuple with the last computed property value and the last time
51 it was updated in seconds since the epoch.
53 The default time-to-live (TTL) is 0, which also means the cache never expires.
55 To expire a cached property value manually just do::
57 del instance._cache[<property name>]
59 © 2011 Christopher Arndt, MIT License
60 source: https://wiki.python.org/moin/PythonDecoratorLibrary#Cached_Properties
63 def __init__(self
, ttl
=0):
66 def __call__(self
, fget
, doc
=None):
68 self
.__doc
__ = doc
or fget
.__doc
__
69 self
.__name
__ = fget
.__name
__
70 self
.__module
__ = fget
.__module
__
73 def __get__(self
, inst
, owner
):
76 value
, last_update
= inst
._cache
[self
.__name
__]
77 if self
.ttl
> 0 and now
- last_update
> self
.ttl
:
79 except (KeyError, AttributeError):
80 value
= self
.fget(inst
)
83 except AttributeError:
84 cache
= inst
._cache
= {}
85 cache
[self
.__name
__] = (value
, now
)