Nested Scopes unintended behaviour ?
Emile van Sebille
emile at fenx.com
Wed Mar 17 11:44:03 EDT 2010
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. You can get around it like:
>
> Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15)
> [GCC 4.4.1] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> def Toggler(F, B):
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ...
>>>> def Switcher(A,B):
> ... on=True
> ... def swtchfun(msg):
---> def swtchfun(msg, on=on):
> ... on_ = on
> ... if on:
> ... on = False
> ... print "Switched to A"
> ... return A
> ... else:
> ... print "Switched to B"
> ... return B
> ... #
> ... return Toggler(swtchfun,True)
> ...
>>>> Switcher(1,2)
> Traceback (most recent call last):
> File "<stdin>", line 1, in<module>
> File "<stdin>", line 13, in Switcher
> File "<stdin>", line 2, in Toggler
> File "<stdin>", line 4, in swtchfun
> UnboundLocalError: local variable 'on' referenced before assignment
>
> The reason I ask is because logically it makes sense. The on_ = on
> statement should resolve "on" to be the value on in the enclosing
> scope, however it appears that the "on = False" statement is taking
> priority. The reason I say this is because if you remove the "on =
> False" line you get the expected name resolution:
>
>>>> def Toggler(F, B):
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ...
>>>> def Switcher(A,B):
> ... on=True
> ... def swtchfun(msg):
> ... on_ = on
> ... if on:
> ... print "Switched to A"
> ... return A
> ... else:
> ... print "Switched to B"
> ... return B
> ... #
> ... return Toggler(swtchfun,True)
> ...
>>>> Switcher(1,2)
> Switched to A
> 1
>
> ie it looks like python is not looking at the expected scope in the
> first instance.
>
> To me it looks like a bug, but I can also see a rationale where it's
> considered a feature (because the "on" is on the left hand side
> resolving the value to a local, rather than a value in an enclosed
> scope)
>
> I know that you can work around this as follows:
> Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15)
> [GCC 4.4.1] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> def Toggler(F, B):
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ... print F("Hello")
> ...
>>>> def Switcher(A,B):
> ... def switchgen():
> ... while True:
> ... yield A
> ... yield B
> ... G = switchgen()
> ... def swtchfun(msg):
> ... return G.next()
> ... #
> ... return Toggler(swtchfun,True)
> ...
>>>>
>>>> Switcher(1,2)
> 1
> 2
> 1
> 2
>
> But I'm curious as to whether the nested scope issue above is
> considered a bug or a feature, so I can deal with it appropriately.
>
> Any comments welcome :-)
>
> Regards,
>
>
> Michael.
> --
> http://yeoldeclue.com/blog
> http://www.kamaelia.org/Home.html
> http://twitter.com/kamaelian
>
>
>
More information about the Python-list
mailing list