Tuesday, January 26, 2010

Closures in Python

A question came up on Stack Overflow about nested functions and closures.

According to wikipedia, 'a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be "closed over" its free variables.' An example should make it clearer.

def adder(n):
def func(x):
return x + n
return func


adder is a so-called factory function. We exercise it like so:

>>> i = 2
>>> f = adder(i)
>>> f(10)
12
>>> j = 3
>>> g = adder(j)
>>> g(10)
13


So the question on SO was, "why does the nested function" (func, assigned to f) "remember the first value" of n?

One answer is: because that's the rule!

>>> hex(id(i))
'0x100202810'
>>> f
<function func at 0x100479050>
>>> f.func_closure
(<cell at 0x10048fde0: int object at 0x100202810>,)


f.func_closure is a tuple. The first item is a "cell" that contains the same int object passed to adder in constructing f.

>>> hex(id(f.func_closure[0].cell_contents))
'0x100202810'


More about function objects here