How do lexical closures work? How do lexical closures work? python python

How do lexical closures work?


Python is actually behaving as defined. Three separate functions are created, but they each have the closure of the environment they're defined in - in this case, the global environment (or the outer function's environment if the loop is placed inside another function). This is exactly the problem, though - in this environment, i is mutated, and the closures all refer to the same i.

Here is the best solution I can come up with - create a function creater and invoke that instead. This will force different environments for each of the functions created, with a different i in each one.

flist = []for i in xrange(3):    def funcC(j):        def func(x): return x * j        return func    flist.append(funcC(i))for f in flist:    print f(2)

This is what happens when you mix side effects and functional programming.


The functions defined in the loop keep accessing the same variable i while its value changes. At the end of the loop, all the functions point to the same variable, which is holding the last value in the loop: the effect is what reported in the example.

In order to evaluate i and use its value, a common pattern is to set it as a parameter default: parameter defaults are evaluated when the def statement is executed, and thus the value of the loop variable is frozen.

The following works as expected:

flist = []for i in xrange(3):    def func(x, i=i): # the *value* of i is copied in func() environment        return x * i    flist.append(func)for f in flist:    print f(2)


Here's how you do it using the functools library (which I'm not sure was available at the time the question was posed).

from functools import partialflist = []def func(i, x): return x * ifor i in xrange(3):    flist.append(partial(func, i))for f in flist:    print f(2)

Outputs 0 2 4, as expected.