Better @memoized decorator.

This commit is contained in:
Todd Gamblin 2015-07-07 00:25:20 -07:00
parent da98b07624
commit 92f398a897

View File

@ -26,6 +26,7 @@
import re
import sys
import functools
import collections
import inspect
# Ignore emacs backups when listing modules
@ -170,16 +171,32 @@ def has_method(cls, name):
return False
def memoized(obj):
class memoized(object):
"""Decorator that caches the results of a function, storing them
in an attribute of that function."""
cache = obj.cache = {}
@functools.wraps(obj)
def memoizer(*args, **kwargs):
if args not in cache:
cache[args] = obj(*args, **kwargs)
return cache[args]
return memoizer
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
if not isinstance(args, collections.Hashable):
# Not hashable, so just call the function.
return self.func(*args)
if args not in self.cache:
self.cache[args] = self.func(*args)
return self.cache[args]
def __get__(self, obj, objtype):
"""Support instance methods."""
return functools.partial(self.__call__, obj)
def clear(self):
"""Expunge cache so that self.func will be called again."""
self.cache.clear()
def list_modules(directory, **kwargs):