From c8eddb7d2296f823af809c1606e5ab561f6de1b4 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 24 Mar 2014 13:00:01 +0100 Subject: [PATCH] [ADD] openerp.tools.func.lazy_property(): Decorator for a lazy property of an object, i.e., an object attribute that is determined by the result of a method call evaluated once. To reevaluate the property, simply delete the attribute on the object, and get it again. bzr revid: chs@openerp.com-20140324120001-935d90ye7tb8a5q4 --- openerp/tools/func.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/openerp/tools/func.py b/openerp/tools/func.py index ca8bba6bd49..89cdf9fb622 100644 --- a/openerp/tools/func.py +++ b/openerp/tools/func.py @@ -3,7 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). -# Copyright (C) 2010 OpenERP s.a. (). +# Copyright (C) 2010, 2014 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -20,11 +20,39 @@ # ############################################################################## -__all__ = ['synchronized'] +__all__ = ['synchronized', 'lazy_property'] from functools import wraps from inspect import getsourcefile + +class lazy_property(object): + """ Decorator for a lazy property of an object, i.e., an object attribute + that is determined by the result of a method call evaluated once. To + reevaluate the property, simply delete the attribute on the object, and + get it again. + """ + def __init__(self, fget): + self.fget = fget + self.name = fget.__name__ + + def __get__(self, obj, cls): + if obj is None: + return self + value = self.fget(obj) + setattr(obj, self.name, value) + return value + + @staticmethod + def reset_all(obj): + """ Reset all lazy properties on the instance `obj`. """ + cls = type(obj) + obj_dict = obj.__dict__ + for name in obj_dict.keys(): + if isinstance(getattr(cls, name, None), lazy_property): + obj_dict.pop(name) + + def synchronized(lock_attr='_lock'): def decorator(func): @wraps(func)