from time import time def memoize(timeout, dynamic_timeout=False): """ Memoization decorator with support for timeout. If dynamic_timeout is set, the cache timeout is doubled if the cached function takes longer time to run than the timeout time """ cache = {"timeout":timeout} def decorator(func): def wrapper(*args, **kwargs): start = time() if (not "time" in cache) or (start - cache["time"] > cache["timeout"]): # cache miss cache["result"] = func(*args, **kwargs) cache["time"] = time() if dynamic_timeout and cache["time"] - start > cache["timeout"]: cache["timeout"] *= 2 return cache["result"] def clear_cache(): if "time" in cache: del cache["time"] if "result" in cache: del cache["result"] wrapper.clear_cache = clear_cache return wrapper return decorator