0

I am looking at some learning material here: http://anandology.com/python-practice-book/functional-programming.html#higher-order-functions-decorators

Particularly the Memoize section, in which the following code is used as an example for higher-order functions:

def memoize(f):
    cache = {}
    def g(x):
        if x not in cache:
            cache[x] = f(x)
        return cache[x]
    return g

It was my understanding that the function returned by memoize would not have access to the "cache" variable since it is out of scope of the definition of "g".

Eg. if I do result_function = memoize(some_function) that result_function would have no knowledge of any cache variable since it is declared outside the g function and the g function alone is returned. Why does it work, and not throw an error?

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
dismantle
  • 91
  • 2
  • 6
  • 3
    I think the word you're looking for is 'closure'. – polku Jul 22 '16 at 11:55
  • It works because being "out-of-scope" doesn't mean that you don't have access to it. Every variable in higher scope is bound to functions defined in that scope (and via recursion to its child scopes) unless these functions do not actually use them (in which case the interpreter will simply garbage collect it). Similarly (but not entirely the same) you can use global variables in any function. – freakish Jul 22 '16 at 11:56

2 Answers2

1

the def memoize(): line introduces a new scope. the g function code 'sees' the scope of its enclosing function. Sure do look into this question's answers: Short Description of the Scoping Rules?.

So no: that's not an error! It's a very nice feature.

Community
  • 1
  • 1
xtofl
  • 40,723
  • 12
  • 105
  • 192
0

the cache object and g(x) object both have the same scope as they are both objects in the memoize function. This means that g(x) will have access to cache because they are both objects scoped in the memoize function.

drxl
  • 364
  • 1
  • 7