Using arguments in a decorator

Jon Clements joncle at googlemail.com
Sat Apr 21 05:37:10 EDT 2012


On Saturday, 21 April 2012 09:25:40 UTC+1, Steven D'Aprano  wrote:
> On Fri, 20 Apr 2012 09:10:15 -0700, Jon Clements wrote:
> 
> >> 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?
> > 
> > Possibly take a look at functools.lru_cache (which is Python 3.2+), and
> > use the code from that (at it's part of the stdlib, someone must have
> > done design and testing on it!).
> 
> With respect Jon, did you read the Original Poster's question closely? 
> Using a LRU cache doesn't even come close to fixing his problem, which 
> occurs *before* you do the lookup in the cache.

I did indeed Steven - what I was suggesting was that functools.lru_cache would be a good starting point. Although I will completely admit that I didn't read the code for functools.lru_cache thoroughly enough to realise it wouldn't be suitable for the OP (ie, it sounded right, looked okay at a glance, and I figured it wasn't a totally unreasonable assumption of a suggestion - so guess I fell into the old 'assume' trap! [not the first time, and won't be the last for sure!])

> 
> Rotwang's problem is that if you have a function with default arguments:
> 
> def func(spam=42):
>     return result_of_time_consuming_calculation()
> 
> then these three function calls are identical and should (but don't) 
> share a single cache entry:
> 
> func()
> func(42)
> func(spam=42)
> 
> The OP would like all three to share a single cache entry without needing 
> two redundant calculations, which take a long time.
> 
> The problem is that the three calls give three different patterns of args 
> and kwargs:
> 
> (), {}
> (42,) {}
> (), {'spam': 42}
> 
> hence three different cache entries, two of which are unnecessary.

I'm wondering if it wouldn't be unreasonable for lru_cache to handle this.

Cheers, Jon.






More information about the Python-list mailing list