On Mar 17, 8:29 pm, Terry Reedy <tjre...@udel.edu> wrote: > On 3/17/2010 11:44 AM, Emile van Sebille wrote: > > > On 3/17/2010 8:16 AM Michael Sparks said... > >> Hi, > > >> Is the following behaviour expected ? > > > In short, yes. Assignment within a function forces the variable to > > locals. > > In 3.x, one can declare names to be nonlocal (ie, local to some outer > function, as opposed to local to the current function or module global). > In your case, > nonlocal on > in your inner swtchfun function would give the behavior you wanted.
Ah, excellent. That makes python closures work more like I'd expect them to. (A colleague had written the swtchfun I posted, whereas the generator form was the version I wrote, and he was puzzled as to why it didn't work as he expected. When I saw it I also couldn't see why. After hearing it's expected behaviour in 2.6 it's clear that assigning a name to a value declares the variable to be local, and that unlike much of python (but like yield) this appears based on static analysis of the function declaration, rather than dynamic. This does also make sense since it prevents a name "switching scope" in a function, and a "nonlocal" keyword also makes sense as a result. Thanks to Emile for pointing out you can also do this in 2.6: def Toggler(F, B): print F("Hello") print F("Hello") print F("Hello") print F("Hello") print F("Hello") def Switcher(A,B): enclose={"on" : True} def swtchfun(msg, enclose=enclose): if enclose["on"]: enclose["on"] = False print "Switched to A" return A else: enclose["on"] = True print "Switched to B" return B # return Toggler(swtchfun,True) Switcher(1,2) I think personally I'd use the generator form myself, since I think it's clearer (more clearly loops between the two), but this may be a useful thing to know occasionally. Cheers :-) Michael. -- http://mail.python.org/mailman/listinfo/python-list