Created
July 19, 2017 12:19
-
-
Save anti1869/8c9d13f9dbf02f93e59ed28b5d3d9962 to your computer and use it in GitHub Desktop.
Memoize for limited number of calls. After that - recalculate and save again
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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