diff --git a/kivy/utils.py b/kivy/utils.py index e43742293..1130db85c 100644 --- a/kivy/utils.py +++ b/kivy/utils.py @@ -10,7 +10,7 @@ __all__ = ('intersection', 'difference', 'strtotuple', 'is_color_transparent', 'boundary', 'deprecated', 'SafeList', 'interpolate', 'OrderedDict', 'QueryDict', - 'platform', 'escape_markup') + 'platform', 'escape_markup', 'reify') from sys import platform as _sys_platform from re import match, split @@ -370,3 +370,28 @@ def escape_markup(text): ''' return text.replace('[', '&bl;').replace(']', '&br;').replace('&', '&') + +class reify(object): + ''' + Put the result of a method which uses this (non-data) descriptor decorator + in the instance dict after the first call, effectively replacing the + decorator with an instance variable. + + It acts like @property, except that the function is only ever called once; + after that, the value is cached as a regular attribute. This gives you lazy + attribute creation on objects that are meant to be immutable. + + Taken from Pyramid project. + ''' + + def __init__(self, func): + self.func = func + self.__doc__ = func.__doc__ + + def __get__(self, inst, cls): + if inst is None: + return self + retval = self.func(inst) + setattr(inst, self.func.__name__, retval) + return retval +