OLD | NEW |
---|---|
(Empty) | |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 class cached_property(object): | |
Vadim Sh.
2014/06/27 18:26:22
Mention somewhere that it's not thread safe.
iannucci
2014/06/28 08:33:35
Done.
| |
6 """Like @property, except that the result of get is cached on | |
7 self.{'_' + fn.__name__}. | |
8 | |
9 >>> class Test(object): | |
10 ... @cached_property | |
11 ... def foo(self): | |
12 ... print "hello" | |
13 ... return 10 | |
14 ... | |
15 >>> t = Test() | |
16 >>> t.foo | |
17 hello | |
18 10 | |
19 >>> t.foo | |
20 10 | |
21 >>> t.foo = 20 | |
22 >>> t.foo | |
23 20 | |
24 >>> del t.foo | |
25 >>> t.foo | |
26 hello | |
27 10 | |
28 >>> | |
29 """ | |
30 def __init__(self, fn): | |
31 self.func = fn | |
32 self._iname = "_" + fn.__name__ | |
33 self.__name__ = fn.__name__ | |
Vadim Sh.
2014/06/27 18:26:22
Use functools.update_wrapper, it's exactly what it
iannucci
2014/06/28 08:33:35
Done.
| |
34 self.__doc__ = fn.__doc__ | |
35 self.__module__ = fn.__module__ | |
36 | |
37 def __get__(self, inst, cls=None): | |
38 if inst is None: | |
39 return self | |
40 if not hasattr(inst, self._iname): | |
41 val = self.func(inst) | |
42 # Some methods call out to another layer to calculate the value. This | |
43 # higher layer will assign directly to the property, so we have to do | |
44 # the extra hasattr here to determine if the value has been set as a side | |
45 # effect of func() | |
46 if not hasattr(inst, self._iname): | |
47 setattr(inst, self._iname, val) | |
48 return getattr(inst, self._iname) | |
49 | |
50 def __delete__(self, inst): | |
51 assert inst is not None | |
52 if hasattr(inst, self._iname): | |
53 delattr(inst, self._iname) | |
OLD | NEW |