Chromium Code Reviews| Index: infra/libs/decorators/decorators.py |
| diff --git a/infra/libs/decorators/decorators.py b/infra/libs/decorators/decorators.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1ea10d92f4513e3a748f9c973905e146d919011a |
| --- /dev/null |
| +++ b/infra/libs/decorators/decorators.py |
| @@ -0,0 +1,53 @@ |
| +# Copyright 2014 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +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.
|
| + """Like @property, except that the result of get is cached on |
| + self.{'_' + fn.__name__}. |
| + |
| + >>> class Test(object): |
| + ... @cached_property |
| + ... def foo(self): |
| + ... print "hello" |
| + ... return 10 |
| + ... |
| + >>> t = Test() |
| + >>> t.foo |
| + hello |
| + 10 |
| + >>> t.foo |
| + 10 |
| + >>> t.foo = 20 |
| + >>> t.foo |
| + 20 |
| + >>> del t.foo |
| + >>> t.foo |
| + hello |
| + 10 |
| + >>> |
| + """ |
| + def __init__(self, fn): |
| + self.func = fn |
| + self._iname = "_" + fn.__name__ |
| + 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.
|
| + self.__doc__ = fn.__doc__ |
| + self.__module__ = fn.__module__ |
| + |
| + def __get__(self, inst, cls=None): |
| + if inst is None: |
| + return self |
| + if not hasattr(inst, self._iname): |
| + val = self.func(inst) |
| + # Some methods call out to another layer to calculate the value. This |
| + # higher layer will assign directly to the property, so we have to do |
| + # the extra hasattr here to determine if the value has been set as a side |
| + # effect of func() |
| + if not hasattr(inst, self._iname): |
| + setattr(inst, self._iname, val) |
| + return getattr(inst, self._iname) |
| + |
| + def __delete__(self, inst): |
| + assert inst is not None |
| + if hasattr(inst, self._iname): |
| + delattr(inst, self._iname) |