RE: Misunderstanding about closures

Discussion in 'Python' started by Robert Brewer, Jun 7, 2004.

  1. 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
    Robert Brewer, Jun 7, 2004
    #1
    1. Advertising

  2. Robert Brewer

    Hung Jung Lu Guest

    "Robert Brewer" <> 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
    Hung Jung Lu, Jun 7, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Hobley

    vec - a misunderstanding

    Mark Hobley, Mar 18, 2006, in forum: Perl
    Replies:
    1
    Views:
    2,589
    John Bokma
    Mar 18, 2006
  2. Kevin Spencer

    Re: Class property misunderstanding

    Kevin Spencer, Jun 26, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    819
    Kevin Spencer
    Jun 26, 2003
  3. Philip Tripp

    View State Misunderstanding

    Philip Tripp, Jul 24, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    511
    Philip Tripp
    Jul 26, 2004
  4. Shawn Wildermuth

    Misunderstanding ConnectionStrings?

    Shawn Wildermuth, Jan 9, 2006, in forum: ASP .Net
    Replies:
    6
    Views:
    1,902
    Steven Cheng[MSFT]
    Jan 11, 2006
  5. Alexander May

    Misunderstanding about closures

    Alexander May, Jun 7, 2004, in forum: Python
    Replies:
    14
    Views:
    586
    Jacek Generowicz
    Jun 17, 2004
Loading...

Share This Page