Nested Scopes unintended behaviour ?

Michael Sparks sparks.m at gmail.com
Wed Mar 17 11:16:49 EDT 2010


Hi,


Is the following behaviour expected ?

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):
...         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