On Thu, 25 Jan 2007 04:29:35 -0800, Paul Rubin wrote: > "gangesmaster" <[EMAIL PROTECTED]> writes: >> what i see as a bug is this code not working as expected: >> >> >>> def make_foos(names): >> ... funcs = [] >> ... for n in names: >> ... def foo(): >> ... print "my name is", n >> ... funcs.append(foo) >> ... return funcs > > But it does work as expected, if your expectations are based on what > closures actually do. > >> i have to create yet another closure, make_foo, so that the name >> is correctly bound to the object, rather than the frame's slot: > > The Python idiom is: > > def make_foos(names): > funcs = [] > for n in names: > def foo(n=n): > print "my name is", n > funcs.append(foo) > return funcs > > The n=n in the "def foo" creates the internal binding that you need.
Hmmm... I thought that the introduction of nested scopes removed the need for that idiom. Its an ugly idiom, the less I see it the happier I am. And I worry that it will bite you on the backside if your "n=n" is a mutable value. My solution is, don't try to have one function do too much. Making a list of foos should be a separate operation from making a single foo: >>> def makefoo(name): ... def foo(): ... return "my name is " + name ... return foo ... >>> makefoo("fred")() 'my name is fred' >>> def makefoos(names): ... foos = [] ... for name in names: ... foos.append(makefoo(name)) ... return foos ... >>> L = makefoos(["fred", "wilma"]) >>> L[0]() 'my name is fred' >>> L[1]() 'my name is wilma' That makes it easier to do unit testing too: you can test your makefoo function independently of your makefoos function, if that's important. If you absolutely have to have everything in one function: >>> def makefoos(names): ... def makefoo(name): ... def foo(): ... return "my name is " + name ... return foo ... L = [] ... for name in names: ... L.append(makefoo(name)) ... return L ... >>> L = makefoos(["betty", "barney"]) >>> L[0]() 'my name is betty' >>> L[1]() 'my name is barney' Best of all, now I don't have to argue as to which binding behaviour is more correct for closures!!! *wink* -- Steven. -- http://mail.python.org/mailman/listinfo/python-list