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
--
http://mail.python.org/mailman/listinfo/python-list