KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
So I recently asked a question about memoization and got some great answers, and now I want to take it to the next level. After quite a bit of googling, I could not find a reference implementation of a memoize decorator that was able to cache a function that took keyword arguments. In fact, most of them simply used *args as the key for cache lookups, meaning that it would also break if you wanted to memoize a function that accepted lists or dicts as arguments. In my case, the first argument to the function is a unique identifier by itself, suitable for use as a dict key for cache lookups, however I wanted the ability to use keyword arguments and still access the same cache. What I mean is, my_func('unique_id', 10) and my_func(foo=10, func_id='unique_id') should both return the same cached result. In order to do this, what we need is a clean and pythonic way of saying 'inspect kwargs for whichever keyword it is that corresponds to the first argument)'. This is what I came up with: class memoize(object): def __init__(self, cls): if type(cls) is FunctionType: # Let's just pretend that the function you gave us is a class. cls.instances = {} cls.__init__ = cls self.cls = cls self.__dict__.update(cls.__dict__) def __call__(self, *args, **kwargs): """Return a cached instance of the appropriate class if it exists.""" # This is some dark magic we're using here, but it's how we discover # that the first argument to Photograph.__init__ is 'filename', but the # first argument to Camera.__init__ is 'camera_id' in a general way. delta = 2 if type(self.cls) is FunctionType else 1 first_keyword_arg = [k for k, v in inspect.getcallargs( self.cls.__init__, 'self', 'first argument', *['subsequent args'] * (len(args) + len
Tags (comma-separated)
Save Edits
Cancel