Last active
December 30, 2015 13:29
-
-
Save dchaplinsky/7835681 to your computer and use it in GitHub Desktop.
Version of @memoize decorator which works with redis backend.
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
| # -*- coding: utf-8 -*- | |
| from functools import partial | |
| from redis import Redis | |
| import settings | |
| redis_client = Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, | |
| db=settings.REDIS_DB) | |
| class memoize(object): | |
| """cache the return value of a method | |
| Author: Daniel Miller, | |
| http://code.activestate.com/recipes/577452-a-memoize-decorator-for-instance-methods/ | |
| 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, foo=None): | |
| 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 | |
| class redis_memoize(memoize): | |
| def __call__(self, *args, **kw): | |
| obj = args[0] | |
| if hasattr(self, "__prefix__"): | |
| prefix = self.__prefix__ | |
| else: | |
| prefix = "%s.%s.%s" % (obj.__class__.__name__, | |
| obj.__module__, | |
| self.func.__name__) | |
| key = (prefix, args[1:], tuple(frozenset(kw.items()))) | |
| if redis_client.exists(key): | |
| res = redis_client.get(key) | |
| else: | |
| res = self.func(*args, **kw) | |
| redis_client.set(key, res) | |
| return res |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment