lazy.py
62 lines
| 1.5 KiB
| text/x-python
|
PythonLexer
r3475 | class _Missing(object): | |||
def __repr__(self): | ||||
return 'no value' | ||||
def __reduce__(self): | ||||
return '_missing' | ||||
_missing = _Missing() | ||||
r2007 | class LazyProperty(object): | |||
""" | ||||
Decorator for easier creation of ``property`` from potentially expensive to | ||||
calculate attribute of the class. | ||||
Usage:: | ||||
class Foo(object): | ||||
@LazyProperty | ||||
def bar(self): | ||||
print 'Calculating self._bar' | ||||
return 42 | ||||
Taken from http://blog.pythonisito.com/2008/08/lazy-descriptors.html and | ||||
used widely. | ||||
""" | ||||
def __init__(self, func): | ||||
self._func = func | ||||
r2494 | self.__module__ = func.__module__ | |||
r2007 | self.__name__ = func.__name__ | |||
self.__doc__ = func.__doc__ | ||||
def __get__(self, obj, klass=None): | ||||
if obj is None: | ||||
r2494 | return self | |||
r3475 | value = obj.__dict__.get(self.__name__, _missing) | |||
if value is _missing: | ||||
value = self._func(obj) | ||||
obj.__dict__[self.__name__] = value | ||||
return value | ||||
r3050 | ||||
import threading | ||||
class ThreadLocalLazyProperty(LazyProperty): | ||||
""" | ||||
Same as above but uses thread local dict for cache storage. | ||||
""" | ||||
def __get__(self, obj, klass=None): | ||||
if obj is None: | ||||
return self | ||||
if not hasattr(obj, '__tl_dict__'): | ||||
obj.__tl_dict__ = threading.local().__dict__ | ||||
r3475 | value = obj.__tl_dict__.get(self.__name__, _missing) | |||
if value is _missing: | ||||
value = self._func(obj) | ||||
obj.__tl_dict__[self.__name__] = value | ||||
return value | ||||