Function decorator that caches function results
Paul Rubin
http
Sun Oct 9 05:49:38 EDT 2005
Steven D'Aprano <steve at REMOVETHIScyber.com.au> writes:
> > def cache_function(fn):
> > cache = {}
> > def cached_result(*args, **kwargs):
> > if args in cache:
> > return cache[args]
> > result = fn(*args, **kwargs)
> > cache[args] = result
> > return result
> > return cached_result
>
> I'm curious... where does cache live after you use cache_function to
> memoize some function? It doesn't appear to be an attribute of the newly
> memoized function, nor does it look like a global variable.
It's in the closure returned by cache_function. cached_result doesn't
change the value of 'cache' (it only changes the boxed content),
cached_result finds it in the outer scope, so you can get away with
that in Python. You couldn't do something like:
def counter():
n = 0
def k():
n += 1 # rebinds n, so Python thinks n is local, oops
return n
return k
Since k changes the value of n, Python thinks n is local to k, and
you get a NameError when you try to increment it the first time.
That you can't set the value of a closure variable is something of a
Python wart and is one of the things that makes me want a "local"
declaration in Python.
Closures are a Scheme idiom and Pythonistas tend to use class
instances instead, but both techniques are useful.
More information about the Python-list
mailing list