Velocity Reviews > RE: Misunderstanding about closures

Robert Brewer
Guest
Posts: n/a

 06-07-2004
Alexander May wrote:
> When I define a function in the body of a loop, why doesn't
> the function "close" on the loop variable?
>
> >>> l=[]
> >>> for x in xrange(10):

> ... def f():
> ... return x
> ... l.append(f)
> ...
> >>> for f in l:

> ... f()
> ...
> 9
> 9
> 9

....because "for" does have it's own scope. The 'x' which is bound in the
'for' statement persists in locals(), and it equals 9 after the 'for'
terminates. Calling each f() simply looks up x in locals() each time;
there's nothing going on in f() which tells Python that x should be in
f's scope. That would require an assignment to x within f, usually.

You could trot out the 'default arg' hack to work around this:

>>> l = []
>>> for x in xrange(10):

.... def f(y=x):
.... return y
.... l.append(f)
....
>>> x

9
>>> [f() for f in l]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Robert Brewer
MIS
Amor Ministries

Hung Jung Lu
Guest
Posts: n/a

 06-07-2004
"Robert Brewer" <(E-Mail Removed)> wrote:
> Alexander May wrote:
> >
> > >>> l=[]
> > >>> for x in xrange(10):

> > ... def f():
> > ... return x
> > ... l.append(f)
> > ...
> > >>> for f in l:

> > ... f()
> > ...
> > 9
> > 9
> > 9

>
> ...because "for" does have it's own scope. The 'x' which is bound in the
> 'for' statement persists in locals(), and it equals 9 after the 'for'
> terminates. Calling each f() simply looks up x in locals() each time;
> there's nothing going on in f() which tells Python that x should be in
> f's scope. That would require an assignment to x within f, usually.

Mostly correct. Except that, in this particular example, the returned
'x' value is pulled from globals() instead of locals(). The locals()
dictionary is empty inside f()'s scope. To see this, run the code:

------------ run in console
l=[]
for x in range(10):
def f():
print 'locals', locals().keys()
print 'globals', globals().keys()
return x
l.append(f)
for f in l:
f()
------------ output
locals []
globals ['x', '__builtins__', '__name__', 'f', '__doc__', 'l']
9
.....

regards,

Hung Jung