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 import functools | |
6 | |
7 | |
8 class cached_property(object): | |
9 """Like @property, except that the result of get is cached on | |
10 self.{'_' + fn.__name__}. | |
11 | |
12 NOTE: This implementation is not threadsafe. | |
13 | |
14 >>> class Test(object): | |
agable
2014/07/25 21:03:38
Too bad we're not actually testing these interpret
iannucci
2014/07/26 00:18:42
yeah
| |
15 ... @cached_property | |
16 ... def foo(self): | |
17 ... print "hello" | |
18 ... return 10 | |
19 ... | |
20 >>> t = Test() | |
21 >>> t.foo | |
22 hello | |
23 10 | |
24 >>> t.foo | |
25 10 | |
26 >>> t.foo = 20 | |
27 >>> t.foo | |
28 20 | |
29 >>> del t.foo | |
30 >>> t.foo | |
31 hello | |
32 10 | |
33 >>> | |
34 """ | |
35 def __init__(self, fn): | |
36 self.func = fn | |
37 self._iname = "_" + fn.__name__ | |
38 functools.update_wrapper(self, fn) | |
39 | |
40 def __get__(self, inst, cls=None): | |
agable
2014/07/25 21:03:38
pylint unusued argument cls
iannucci
2014/07/26 00:18:42
It's part of the function signature so pylint does
| |
41 if inst is None: | |
42 return self | |
43 if not hasattr(inst, self._iname): | |
44 val = self.func(inst) | |
45 # Some methods call out to another layer to calculate the value. This | |
46 # higher layer will assign directly to the property, so we have to do | |
47 # the extra hasattr here to determine if the value has been set as a side | |
48 # effect of func() | |
49 if not hasattr(inst, self._iname): | |
50 setattr(inst, self._iname, val) | |
51 return getattr(inst, self._iname) | |
52 | |
53 def __delete__(self, inst): | |
54 assert inst is not None | |
55 if hasattr(inst, self._iname): | |
56 delattr(inst, self._iname) | |
OLD | NEW |