Skip to content

Instantly share code, notes, and snippets.

@anti1869
Created July 19, 2017 12:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anti1869/8c9d13f9dbf02f93e59ed28b5d3d9962 to your computer and use it in GitHub Desktop.
Save anti1869/8c9d13f9dbf02f93e59ed28b5d3d9962 to your computer and use it in GitHub Desktop.
Memoize for limited number of calls. After that - recalculate and save again
import functools
__all__ = ("memoize", )
MEMOIZE_CACHE = {}
class _memoize(object):
"""
Memoize the function being decorated so that subsequent calls with the same
arguments are pulled from a cache that contains the previously collected
result. When using this decorator you can easily add memoization capabilities
to your function without cluttering it with code that is prone to errors.
https://github.com/rlgomes/memoize/blob/master/memoize.py
"""
times = None
def __init__(self, function):
self.__f = function
self.__f_get = self.__f.__get__
functools.update_wrapper(self, function)
def __call__(self, *args, **kwargs):
func_name = getattr(self.__f, '__name__', None) or self.__f.func_name
argkey = (func_name, str(args), str(kwargs))
if argkey in MEMOIZE_CACHE:
if self.times is None:
return MEMOIZE_CACHE[argkey]["value"]
MEMOIZE_CACHE[argkey]["called"] += 1
if MEMOIZE_CACHE[argkey]["called"] >= self.times:
return self._call_for_ret(argkey, *args, **kwargs)
else:
return MEMOIZE_CACHE[argkey]["value"]
else:
return self._call_for_ret(argkey, *args, **kwargs)
def _call_for_ret(self, argkey, *args, **kwargs):
ret = self.__f(*args, **kwargs)
MEMOIZE_CACHE[argkey] = {
"called": 1,
"value": ret,
}
return ret
def __get__(self, obj, type=None):
if obj is None:
return self
new_func = self.__f_get(obj, type)
return self.__class__(new_func)
def memoize(times=None):
"""
Decorator to memoize for several or infinite number of calls.
:param times: How many calls to memoize for.
"""
kls = type('Memoize', (_memoize, ), {"times": times})
return kls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment