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

Reply via email to