1 # -*- coding: utf-8 -*-
3 __author__
= 'Daniel Greenfeld'
4 __email__
= 'pydanny@gmail.com'
12 class cached_property(object):
14 A property that is only computed once per instance and then replaces itself
15 with an ordinary attribute. Deleting the attribute resets the property.
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 threaded_cached_property(object):
32 A cached_property version for use in environments where multiple threads
33 might concurrently try to access the property.
36 def __init__(self
, func
):
37 self
.__doc
__ = getattr(func
, '__doc__')
39 self
.lock
= threading
.RLock()
41 def __get__(self
, obj
, cls
):
45 obj_dict
= obj
.__dict
__
46 name
= self
.func
.__name
__
49 # check if the value was computed before the lock was acquired
52 # if not, do the calculation and release the lock
53 return obj_dict
.setdefault(name
, self
.func(obj
))
56 class cached_property_with_ttl(object):
58 A property that is only computed once per instance and then replaces itself
59 with an ordinary attribute. Setting the ttl to a number expresses how long
60 the property will last before being timed out.
63 def __init__(self
, ttl
=None):
70 self
._prepare
_func
(func
)
72 def __call__(self
, func
):
73 self
._prepare
_func
(func
)
76 def __get__(self
, obj
, cls
):
81 obj_dict
= obj
.__dict
__
84 value
, last_updated
= obj_dict
[name
]
88 ttl_expired
= self
.ttl
and self
.ttl
< now
- last_updated
92 value
= self
.func(obj
)
93 obj_dict
[name
] = (value
, now
)
96 def __delete__(self
, obj
):
97 obj
.__dict
__.pop(self
.__name
__, None)
99 def __set__(self
, obj
, value
):
100 obj
.__dict
__[self
.__name
__] = (value
, time())
102 def _prepare_func(self
, func
):
105 self
.__doc
__ = func
.__doc
__
106 self
.__name
__ = func
.__name
__
107 self
.__module
__ = func
.__module
__
109 # Aliases to make cached_property_with_ttl easier to use
110 cached_property_ttl
= cached_property_with_ttl
111 timed_cached_property
= cached_property_with_ttl
114 class threaded_cached_property_with_ttl(cached_property_with_ttl
):
116 A cached_property version for use in environments where multiple threads
117 might concurrently try to access the property.
120 def __init__(self
, ttl
=None):
121 super(threaded_cached_property_with_ttl
, self
).__init
__(ttl
)
122 self
.lock
= threading
.RLock()
124 def __get__(self
, obj
, cls
):
126 return super(threaded_cached_property_with_ttl
, self
).__get
__(obj
,
129 # Alias to make threaded_cached_property_with_ttl easier to use
130 threaded_cached_property_ttl
= threaded_cached_property_with_ttl
131 timed_threaded_cached_property
= threaded_cached_property_with_ttl