Show More
@@ -1,45 +1,62 b'' | |||||
|
1 | class _Missing(object): | |||
|
2 | ||||
|
3 | def __repr__(self): | |||
|
4 | return 'no value' | |||
|
5 | ||||
|
6 | def __reduce__(self): | |||
|
7 | return '_missing' | |||
|
8 | ||||
|
9 | _missing = _Missing() | |||
|
10 | ||||
|
11 | ||||
1 | class LazyProperty(object): |
|
12 | class LazyProperty(object): | |
2 | """ |
|
13 | """ | |
3 | Decorator for easier creation of ``property`` from potentially expensive to |
|
14 | Decorator for easier creation of ``property`` from potentially expensive to | |
4 | calculate attribute of the class. |
|
15 | calculate attribute of the class. | |
5 |
|
16 | |||
6 | Usage:: |
|
17 | Usage:: | |
7 |
|
18 | |||
8 | class Foo(object): |
|
19 | class Foo(object): | |
9 | @LazyProperty |
|
20 | @LazyProperty | |
10 | def bar(self): |
|
21 | def bar(self): | |
11 | print 'Calculating self._bar' |
|
22 | print 'Calculating self._bar' | |
12 | return 42 |
|
23 | return 42 | |
13 |
|
24 | |||
14 | Taken from http://blog.pythonisito.com/2008/08/lazy-descriptors.html and |
|
25 | Taken from http://blog.pythonisito.com/2008/08/lazy-descriptors.html and | |
15 | used widely. |
|
26 | used widely. | |
16 | """ |
|
27 | """ | |
17 |
|
28 | |||
18 | def __init__(self, func): |
|
29 | def __init__(self, func): | |
19 | self._func = func |
|
30 | self._func = func | |
20 | self.__module__ = func.__module__ |
|
31 | self.__module__ = func.__module__ | |
21 | self.__name__ = func.__name__ |
|
32 | self.__name__ = func.__name__ | |
22 | self.__doc__ = func.__doc__ |
|
33 | self.__doc__ = func.__doc__ | |
23 |
|
34 | |||
24 | def __get__(self, obj, klass=None): |
|
35 | def __get__(self, obj, klass=None): | |
25 | if obj is None: |
|
36 | if obj is None: | |
26 | return self |
|
37 | return self | |
27 |
|
|
38 | value = obj.__dict__.get(self.__name__, _missing) | |
28 | return result |
|
39 | if value is _missing: | |
|
40 | value = self._func(obj) | |||
|
41 | obj.__dict__[self.__name__] = value | |||
|
42 | return value | |||
29 |
|
43 | |||
30 | import threading |
|
44 | import threading | |
31 |
|
45 | |||
32 |
|
46 | |||
33 | class ThreadLocalLazyProperty(LazyProperty): |
|
47 | class ThreadLocalLazyProperty(LazyProperty): | |
34 | """ |
|
48 | """ | |
35 | Same as above but uses thread local dict for cache storage. |
|
49 | Same as above but uses thread local dict for cache storage. | |
36 | """ |
|
50 | """ | |
37 |
|
51 | |||
38 | def __get__(self, obj, klass=None): |
|
52 | def __get__(self, obj, klass=None): | |
39 | if obj is None: |
|
53 | if obj is None: | |
40 | return self |
|
54 | return self | |
41 | if not hasattr(obj, '__tl_dict__'): |
|
55 | if not hasattr(obj, '__tl_dict__'): | |
42 | obj.__tl_dict__ = threading.local().__dict__ |
|
56 | obj.__tl_dict__ = threading.local().__dict__ | |
43 |
|
57 | |||
44 |
|
|
58 | value = obj.__tl_dict__.get(self.__name__, _missing) | |
45 | return result |
|
59 | if value is _missing: | |
|
60 | value = self._func(obj) | |||
|
61 | obj.__tl_dict__[self.__name__] = value | |||
|
62 | return value |
General Comments 0
You need to be logged in to leave comments.
Login now