Skip to content

Instantly share code, notes, and snippets.

@luizhenriquefbb
Last active April 16, 2021 15:09
Show Gist options
  • Save luizhenriquefbb/4d2f6863af7bd45b2baeb9478c3d0a8d to your computer and use it in GitHub Desktop.
Save luizhenriquefbb/4d2f6863af7bd45b2baeb9478c3d0a8d to your computer and use it in GitHub Desktop.
timed memoized
import functools
import threading
import time
def timed_memoized(time_to_reset: int = 300):
"""
Decorator that caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned, and
not re-evaluated.
After x seconds, the cache is cleared
Usage:
@timed_memoized(time_to_reset=30)
def my_func(self, val):
print "in my_func"
time.sleep(2)
return val
"""
class _timed_memoized(object):
def __init__(self, func ):
self.func = func
self.cache = {}
self.time_to_reset = time_to_reset
def __call__(self, *args, **key_args):
if args in self.cache:
return self.cache[args]
else:
try:
return self.cache[args]
except KeyError:
value = self.func(*args, **key_args)
self.cache[args] = value
threading.Thread(target=self._sleep_then_reset, args=(args,)).start()
return value
except TypeError:
# uncachable -- for instance, passing a list as an argument.
# Better to not cache than to blow up entirely.
return self.func(*args, **key_args)
def __repr__(self):
"""Return the function's docstring."""
return self.func.__doc__
def __get__(self, obj, objtype):
"""Support instance methods."""
fn = functools.partial(self.__call__, obj)
fn.reset = self._reset
return fn
def _sleep_then_reset(self, args):
time.sleep(self.time_to_reset)
del self.cache[args]
def _reset(self):
self.cache = {}
return _timed_memoized
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment