Created
September 14, 2014 10:31
-
-
Save cmltaWt0/5d9ad690b686a248077b to your computer and use it in GitHub Desktop.
Memoize from ActiveState Code by Daniel Miller
This file contains 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
from functools import partial | |
class memoize(object): | |
"""cache the return value of a method | |
This class is meant to be used as a decorator of methods. The return value | |
from a given method invocation will be cached on the instance whose method | |
was invoked. All arguments passed to a method decorated with memoize must | |
be hashable. | |
If a memoized method is invoked directly on its class the result will not | |
be cached. Instead the method will be invoked like a static method: | |
class Obj(object): | |
@memoize | |
def add_to(self, arg): | |
return self + arg | |
Obj.add_to(1) # not enough arguments | |
Obj.add_to(1, 2) # returns 3, result is not cached | |
""" | |
def __init__(self, func): | |
self.func = func | |
def __get__(self, obj, objtype=None): | |
if obj is None: | |
return self.func | |
return partial(self, obj) | |
def __call__(self, *args, **kw): | |
obj = args[0] | |
try: | |
cache = obj.__cache | |
except AttributeError: | |
cache = obj.__cache = {} | |
key = (self.func, args[1:], frozenset(kw.items())) | |
try: | |
res = cache[key] | |
except KeyError: | |
res = cache[key] = self.func(*args, **kw) | |
return res | |
if __name__ == "__main__": | |
# example usage | |
class Test(object): | |
v = 0 | |
@memoize | |
def inc_add(self, arg): | |
self.v += 1 | |
return self.v + arg | |
t = Test() | |
assert t.inc_add(2) == t.inc_add(2) | |
assert Test.inc_add(t, 2) != Test.inc_add(t, 2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment