Nested Scopes unintended behaviour ?

Michael Sparks sparks.m at gmail.com
Thu Mar 18 06:21:08 EDT 2010


On Mar 17, 8:29 pm, Terry Reedy <tjre... at 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.



More information about the Python-list mailing list