Michael Merickel
2018-10-19 d579f2104de139e0b0fc5d6c81aabb2f826e5e54
commit | author | age
fc47a4 1 from functools import update_wrapper
462af2 2
TS 3
5babba 4 class reify(object):
07cb8f 5     """ Use as a class method decorator.  It operates almost exactly like the
CM 6     Python ``@property`` decorator, but it puts the result of the method it
7     decorates into the instance dict after the first call, effectively
8     replacing the function it decorates with an instance variable.  It is, in
206197 9     Python parlance, a non-data descriptor.  The following is an example and
SP 10     its usage:
07cb8f 11
b5fcc4 12     .. doctest::
SP 13
206197 14         >>> from pyramid.decorator import reify
SP 15
16         >>> class Foo(object):
17         ...     @reify
18         ...     def jammy(self):
19         ...         print('jammy called')
20         ...         return 1
21
b5fcc4 22         >>> f = Foo()
SP 23         >>> v = f.jammy
24         jammy called
25         >>> print(v)
26         1
27         >>> f.jammy
28         1
29         >>> # jammy func not called the second time; it replaced itself with 1
30         >>> # Note: reassignment is possible
31         >>> f.jammy = 2
32         >>> f.jammy
33         2
07cb8f 34     """
0c29cf 35
5babba 36     def __init__(self, wrapped):
CM 37         self.wrapped = wrapped
fc47a4 38         update_wrapper(self, wrapped)
5babba 39
CM 40     def __get__(self, inst, objtype=None):
41         if inst is None:
42             return self
43         val = self.wrapped(inst)
44         setattr(inst, self.wrapped.__name__, val)
45         return val