Created
December 13, 2013 23:53
-
-
Save dchaplinsky/7953723 to your computer and use it in GitHub Desktop.
Weirdest memoize decorator in world (modified version of http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ 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
# -*- coding: utf-8 -*- | |
from functools import wraps, 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(cache_key="foobar") | |
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, cache_key=None): | |
self.cache_key = cache_key | |
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] | |
if not hasattr(self, "func"): | |
self.func = obj | |
return self | |
try: | |
cache = obj.__cache | |
except AttributeError: | |
cache = obj.__cache = {} | |
key = (self.cache_key, self.func, args[1:], frozenset(kw.items())) | |
print(key) | |
try: | |
res = cache[key] | |
except KeyError: | |
res = cache[key] = self.func(*args, **kw) | |
return res |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment