Steven D'Aprano <[EMAIL PROTECTED]> 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. -- http://mail.python.org/mailman/listinfo/python-list