def __new__(cls, name, bases, attrs): # Fix __init__ init = attrs.get('__init__', lambda *args, **kwargs: None) def fixed_init(self, *args, **kwargs): for base in reversed(bases): if base is object: break base.__init__(self, *args, **kwargs) init(self, *args, **kwargs) attrs['__init__'] = function_sync(init, fixed_init) # Fix _update_cache update_cache = attrs.get('_update_cache', None) if not update_cache: for base in reversed(bases): if hasattr(base, '_update_cache'): update_cache = base._update_cache break if update_cache: def fixed_update_cache(self, *args, **kwargs): data = update_cache(self, *args, **kwargs) for base in reversed(bases): if hasattr(base, '_insert_into_cache'): base._insert_into_cache(self, data) break attrs['_update_cache'] = function_sync(update_cache, fixed_update_cache) return type.__new__(cls, name, bases, attrs)
def wrapper_deco(method): def wrapper(self, *args, **kwargs): if (time.time() - self._updated.get('__time', 0)) >= length: self._update_cache() self._updated['__time'] = time.time() return method(self, *args, **kwargs) return function_sync(method, wrapper)
def wrapper_deco(method): def wrapper(self, *args, **kwargs): if self._updated.get('count__' + method.__name__, num) == num: self._update_cache() self._updated['count__' + method.__name__] = 1 else: self._updated['count__' + method] = self._updated.get( 'count__' + method, 0) + 1 return method(self, *args, **kwargs) return function_sync(method, wrapper)
def __new__(cls, name, bases, attrs): # Fix _update_cache update_cache = attrs.get('_update_cache', lambda *args, **kwargs: None) def fixed_update_cache(self, *args, **kwargs): val = update_cache(self, *args, **kwargs) if hasattr(bases[-1], '_update_cache'): bases[-1]._update_cache(self, *args, **kwargs) return val attrs['_update_cache'] = function_sync(update_cache, fixed_update_cache) # Fix __init__ init = attrs.get('__init__', lambda *args, **kwargs: None) def fixed_init(self, *args, **kwargs): if hasattr(bases[-1], '__init__') and bases[-1] is not object: bases[-1].__init__(self, *args, **kwargs) init(self, *args, **kwargs) attrs['__init__'] = function_sync(init, fixed_init) return type.__new__(cls, name, bases, attrs)
def wrapper_deco(method): def wrapper(self, *args, **kwargs): if always: if key not in self._cache: self._update_cache() return method(self, *args, **kwargs) elif (key not in self._cache and (not self._updated.get('key__' + key, False))): self._update_cache() self._updated['key__' + key] = True return method(self, *args, **kwargs) return function_sync(method, wrapper)
def update_once(method): """ Make sure the cache has been updated at least once before calling a method. This should be used as a decorator, and it wraps a method on a cached object to make sure that the object's cache has been updated at least once before the method is called. This allows you to implement lazy evaluation, which is especially useful when fetching data over the network. """ def wrapper(self, *args, **kwargs): if not self._updated.get('__count', 0): self._update_cache() self._updated['__count'] = self._updated.get('__count', 0) + 1 return method(self, *args, **kwargs) return function_sync(method, wrapper)