closures and dynamic binding
Terry Reedy
tjreedy at udel.edu
Sun Sep 28 09:46:57 CEST 2008
Aaron "Castironpi" Brady wrote:
> Hello all,
>
> To me, this is a somewhat unintuitive behavior. I want to discuss the
> parts of it I don't understand.
>
>>>> f= [ None ]* 10
>>>> for n in range( 10 ):
> ... f[ n ]= lambda: n
This is equivalent to
for n in range(10):
def g(): return n
f[n] = g
which is equivalent to
def g(): return n
f = [g]*10
n = 9
>>>> f[0]()
> 9
>>>> f[1]()
> 9
which make this not so surprising as the original lambda version is to
some people.
> I guess I can accept this part so far, though it took a little getting
> used to. I'm writing some code and found the following workaround,
> but I don't think it should give different results. Maybe I'm not
> understanding some of the details of closures.
>
>>>> f= [ None ]* 10
>>>> for n in range( 10 ):
> ... f[ n ]= (lambda n: ( lambda: n ) )( n )
This is equivalent to
for n in range(10):
def g(n):
def h:
return n
return h
f[n] = g(n)
Now, to avoid the needless confusion of 'n's, g is equivalent to
def g(x):
def h:
return x
return h
(One could do the same change in the lambdas, too, of course).
so that g(n)() == n, with n stored in each closure h...
> ...
>>>> f[0]()
> 0
>>>> f[1]()
> 1
to be regurgitated when each is called.
Terry Jan Reedy
More information about the Python-list
mailing list