From 5cdec57926f0c2022329908ce9a74b775ec19841 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Sat, 21 Jun 2014 19:02:50 -0500 Subject: [PATCH] Add memoize_on_first_arg --- pytools/__init__.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/pytools/__init__.py b/pytools/__init__.py index 6cd3205..8bf62b7 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -480,6 +480,47 @@ def memoize_method(method): return new_wrapper +def memoize_on_first_arg(function): + """Like :func:`memoize_method`, but for functions that take the object + to do memoization as first argument. + + Supports cache deletion via ``function_name.clear_cache(self)``. + + .. note:: + *clear_cache* support requires Python 2.5 or newer. + """ + + cache_dict_name = intern("_memoize_dic_" + + function.__module__ + function.__name__) + + def wrapper(obj, *args, **kwargs): + if kwargs: + key = (_HasKwargs, frozenset(kwargs.iteritems())) + args + else: + key = args + + try: + return getattr(obj, cache_dict_name)[key] + except AttributeError: + result = function(obj, *args, **kwargs) + setattr(obj, cache_dict_name, {key: result}) + return result + except KeyError: + result = function(obj, *args, **kwargs) + getattr(obj, cache_dict_name)[key] = result + return result + + def clear_cache(obj): + delattr(obj, cache_dict_name) + + if sys.version_info >= (2, 5): + from functools import update_wrapper + new_wrapper = update_wrapper(wrapper, function) + new_wrapper.clear_cache = clear_cache + + return new_wrapper + + def memoize_method_with_uncached(uncached_args=[], uncached_kwargs=set()): """Supports cache deletion via ``method_name.clear_cache(self)``. -- GitLab