Using arguments in a decorator

Peter Otten __peter__ at web.de
Fri Apr 20 13:14:09 EDT 2012


Rotwang wrote:

> I've written a
> decorator to eliminate repeated calls by storing a dictionary whose
> items are arguments and their results:

> The problem is that the dictionary key
> stored depends on how the function was called, even if two calls should
> be equivalent; hence the original function gets called more often than
> necessary. 

I think you can normalize the arguments with inspect.getcallargs(). A 
sketch:

>>> import inspect
>>> def memo(f):
...     def g(*args, **kw):
...             callargs = tuple(sorted(inspect.getcallargs(f, *args, 
**kw).items()))
...             try:
...                     return cache[callargs]
...             except KeyError:
...                     result = cache[callargs] = f(*args, **kw)
...                     return result
...     cache = {}
...     return g
... 
>>> @memo
... def f(x, y=2):
...     print "calling f(%s, %s)" % (x, y)
...     return x + y
... 
>>> f(1, 2)
calling f(1, 2)
3
>>> f(1)
3
>>> f(y=2, x=1)
3





More information about the Python-list mailing list