Why do closures do this?

John O'Hagan research at johnohagan.com
Sun Aug 28 07:03:13 CEST 2011


On Sun, 28 Aug 2011 00:19:07 -0400
Terry Reedy <tjreedy at udel.edu> wrote:

> On 8/27/2011 11:45 PM, John O'Hagan wrote:
> > Somewhat apropos of the recent "function principle" thread, I was recently surprised by this:
> >
> > funcs=[]
> > for n in range(3):
> >      def f():
> >          return n
> >      funcs.append(f)
> >
> >
> >
> > The last expression, IMO surprisingly, is [2,2,2], not [0,1,2]. 

[...]

> 
> def f(): return n
> is a CONSTANT value. It is not a closure.
 
Quite right: I originally encountered this inside a function, but removed the enclosing function to show the issue in minimal form.
 
> Your code above is the same as
> def f(): return n
> funcs = [f,f,f]
> n = 2
> [i() for i in funcs]
> 

Also right, but I still find this surprising.

[...]

> 
> > My question is, is this an inescapable consequence of using closures,
> 
> I cannot answer since I am not sure what you mean by 'this'.

Ah, but you are and you have:

> Closures are nested functions that access the locals of enclosing 
> functions. To ensure that the access remains possible even after the 
> enclosing function returns, the last value of such accessed names is 
> preserved even after the enclosing function returns. (That is the tricky 
> part.)
> 

Thanks,

John



More information about the Python-list mailing list