Source code for openglider.utils.cached_property

#import functools

#__all__ = ['cached_property']
import functools

config = {"caching": True, 'verbose': False}


[docs]def cached_property(*hashlist): class CachedProperty(object): def __init__(self, fget=None): #super(CachedProperty, self).__init__(fget) self.function = fget self.hashlist = hashlist self.cache = None self.thahash = None functools.update_wrapper(self, fget) def __get__(self, parentclass, _none=None): #__doc__ = self.__doc__ if not config["caching"]: #return super(CachedProperty, self).__get__(parentclass) return self.function(parentclass) else: dahash = hash_attributes(parentclass, self.hashlist) # Return cached or recalc if hashes differ if not self.cache is None and dahash == self.thahash: return self.cache else: self.thahash = dahash #res = super(CachedProperty, self).__get__(parentclass) res = self.function(parentclass) self.cache = res return res # CachedProperty = property # ENABLE FOR SPHINX-APIDOC return CachedProperty
[docs]def rec_getattr(obj, attr): if attr == "self": return obj elif '.' not in attr: return getattr(obj, attr) else: l = attr.split('.') return rec_getattr(getattr(obj, l[0]), '.'.join(l[1:]))
[docs]def c_mul(a, b): """ C type multiplication http://stackoverflow.com/questions/6008026/how-hash-is-implemented-in-python-3-2 """ return eval(hex((int(a) * b) & 0xFFFFFFFF)[:-1])
[docs]def hash_attributes(class_instance, hashlist): """ http://effbot.org/zone/python-hash.htm """ value = 0x345678 for attribute in hashlist: el = rec_getattr(class_instance, attribute) # hash try: thahash = hash(el) except TypeError: # Lists if config['verbose']: print("bad cache: "+str(class_instance.__name__)+" attribute: "+attribute) try: thahash = hash(frozenset(el)) except TypeError: thahash = hash(str(el)) value = c_mul(1000003, value) ^ thahash value = value ^ len(hashlist) if value == -1: value = -2 return value
[docs]class HashedObject(object): """ Provide a list of attributes to hash down for tracking changes """ hashlist = () def __hash__(self): return hash_attributes(self, self.hashlist)
[docs]class test(object): def __init__(self): self.num = 3 @cached_property('num') def neu(self): print("tuwas") return self.num #@neu.reset #def reset(self): # pass #recalc = cache.reset #global config #print(config) #ab = test() #print("jojo") #print(ab.neu) #print(ab.neu)