On Fri, 20 Apr 2012 16:57:06 +0100, Rotwang wrote: > def memo(func): > def memofunc(*args, **kwargs): > twargs = tuple(kwargs.items()) > if (args, twargs) in memofunc.d: > return copy(memofunc.d[(args, twargs)]) > memofunc.d[(args, twargs)] = func(*args, **kwargs) return > copy(memofunc.d[(args, twargs)]) > memofunc.__name__ = func.__name__ > memofunc.d = {} > return memofunc
Note that this decorator is underpowered and arguable buggy: it suppresses the decorated function's doc string. You should use functools.wraps to copy the name, doc string and anything else necessary. Here is how I would write the above. import functools def memoise(func): """Decorator to memoise a function.""" cache = {} @functools.wraps(func) def inner(*args, **kwargs): # Make sure keyword args are always looked up in a consistent # order by sorting. One minor subtlety: since kwargs cannot # have duplicate keys, sorted() will never try to break ties # by comparing values. So this will work even for unsortable # values like complex numbers. kw = tuple(sorted(kwargs.items())) try: # Cache hit? result = cache[(args, kw)] except KeyError: # Cache miss. result = func(*args, **kwargs) cache[(args, kw)] = result except TypeError: # Cache failure; at least one argument is uncacheable. result = func(*args, **kwargs) # Is the cache too big? if len(cache) > 1000: # Dump an arbitrary item. A LRU (least recently used) cache # would be better, but this will do. cache.popitem() return result # Expose the cache to the outside world. inner._cache = cache return inner [...] > But I don't know how. I know that I can see the default arguments of the > original function using func.__defaults__, but without knowing the > number and names of func's positional arguments (which I don't know how > to find out) this doesn't help me. Any suggestions? http://docs.python.org/release/3.1.5/library/inspect.html?#inspect.getfullargspec >>> def f(a, b=1, *args, c, d=2, **kwargs): ... x = 42 ... return (a,b,c,d,args,kwargs) ... >>> import inspect >>> inspect.getfullargspec(f) FullArgSpec(args=['a', 'b'], varargs='args', varkw='kwargs', defaults=(1,), kwonlyargs=['c', 'd'], kwonlydefaults={'d': 2}, annotations={}) -- Steven -- http://mail.python.org/mailman/listinfo/python-list