Skip to content

Instantly share code, notes, and snippets.

@jaylett
Created July 27, 2012 10:04
Show Gist options
  • Save jaylett/3187225 to your computer and use it in GitHub Desktop.
Save jaylett/3187225 to your computer and use it in GitHub Desktop.
Latest memoize
import functools
import cPickle
from django.conf import settings
# shamelessly stolen from
# http://wiki.python.org/moin/PythonDecoratorLibrary?action=recall&rev=111#Memoize
class memoize(object):
'''Decorator. Caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned
(not reevaluated).
'''
cache = {}
pickle_cache = {}
@classmethod
def clear(cls):
cls.cache = {}
cls.pickle_cache = {}
def __init__(self, func):
self.func = func
self.cache_prefix = (func,)
def __call__(self, *args, **kwargs):
if not getattr(settings, "MEMOIZE", True):
return self.func(*args, **kwargs)
if not kwargs:
key = (self.cache_prefix, args)
try:
return self.cache[key]
except KeyError:
value = self.func(*args)
self.cache[key] = value
return value
except TypeError:
# unhashable -- for instance, passing a list or dict as an argument.
# fall through to using pickle
pass
try:
key = (self.cache_prefix, cPickle.dumps(args, 1), cPickle.dumps(kwargs, 1))
except TypeError, e:
# probably have a function being passed in
return self.func(*args, **kwargs)
try:
return self.pickle_cache[key]
except KeyError:
value = self.func(*args, **kwargs)
self.pickle_cache[key] = value
return value
def __repr__(self):
'''Return the function's docstring.'''
return self.func.__doc__
def __get__(self, obj, objtype):
'''Support instance methods.'''
self.cache_prefix = (type(object), obj, self.func)
return functools.partial(self.__call__, obj)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment