python resettable instance method memoization decorator

前端 未结 3 1976
旧巷少年郎
旧巷少年郎 2020-12-16 02:41

I\'m attempting to build a decorator for an instance method of a class that will memoize the result. (This has been done a million times before) However, I\'d like the optio

3条回答
  •  囚心锁ツ
    2020-12-16 02:59

    Rather than trying to work out the mechanics of your implementation, I've taken the memoized decorator class from PythonDecoratorLibrary, and have modified it to add reset. Below is the result; the trick I've used is to add a callable reset attribute to the decorated function itself.

        class memoized2(object):
           """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.
           """
           def __init__(self, func):
              self.func = func
              self.cache = {}
           def __call__(self, *args):
              try:
                 return self.cache[args]
              except KeyError:
                 value = self.func(*args)
                 self.cache[args] = value
                 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)
           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 _reset(self):
              self.cache = {}
    
    
        class my_class:
            @memoized2
            def my_func(self, val):
                print "in my_func"
                time.sleep(2)
                return val
    
    
        c = my_class()
    
        print "should take time"
        print c.my_func(55)
        print
    
        print "should be instant"
        print c.my_func(55)
        print
    
        c.my_func.reset()
    
        print "should take time"
        print c.my_func(55)
    

提交回复
热议问题