[EMAIL PROTECTED] wrote: > On Sat, Oct 08, 2005 at 01:53:28PM +0000, Duncan Booth wrote: > >>Unless the results stored in the cache are very large data structures, I >>would suggest that you simply store (args,kwargs) as the cache key and >>accept the hit that sometime you'll cache the same call multiple times. > > > ... except that dicts cannot be dict keys > > Another 'memoize' decorator uses this to get the key: > kw = kwargs.items() > kw.sort() > key = (args, tuple(kw)) > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/325905 > > Jeff
Yeah, but as far as I can see it, this one too fails to recognize situations where the function is called twice with essentially the same values, except that in one call it uses named arguments: k1 = fibonacci(100) k2 = fibonacci(idx = 100) this is essentially the same call, except the second one uses a named argument, which means the function will be invoked and a second cache entry will be stored. Granted, not a big problem in most such cases, but here's my augmented function. Bare in mind that I'm 2 weeks into Python so there's bound to be room for improvement :) def cache(fn): cache = {} arg_names = inspect.getargspec(fn)[0] def cached_result(*args, **kwargs): # If function is called without parameters, call it without using the cache if len(args) == 0 and len(kwargs) == 0: return fn() # Work out all parameter names and values values = {} for i in range(len(args)): values[arg_names[i]] = args[i] for key in kwargs: values[key] = kwargs[key] key = tuple([(key, value) for (key, value) in sorted(values.iteritems())]) # Check cache and return cached value if possible if key in cache: return cache[key] # Work out new value, cache it and return it result = fn(*args, **kwargs) cache[key] = result return result # Return wrapper function return cached_result -- Lasse Vågsæther Karlsen http://usinglvkblog.blogspot.com/ mailto:[EMAIL PROTECTED] PGP KeyID: 0x2A42A1C2 -- http://mail.python.org/mailman/listinfo/python-list