Mindboggling Scope Issue
James Stroud
jstroud at mbi.ucla.edu
Sun Oct 24 19:16:14 EDT 2004
Hello All,
Please bare with me as I have seldom asked for help with my code, so I may do
things a little wrong at times. If I ask in the wrong way, please by friendly
like Tarry Reedy and suggest how I may better ask my questions.
So I will retry this one from the top, and with Tarry's suggestions
incorporated.
First I'll begin with a simple example that works from the python CLI:
% python
Python 2.3.3 (#2, Feb 17 2004, 11:45:40)
[GCC 3.3.2 (Mandrake Linux 10.0 3.3.2-6mdk)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def outer():
... def inner():
... print bob
... bob = "wuzzup?"
... inner()
...
>>> outer()
wuzzup?
This is an experiment to prove that a function can "de-reference" a name even
if the function is defined in a position of the code that preceeds said
name's assignment in the enclosing scope. (Hopefully my vocabulary makes
sense here--I am not a computer scientist). Please look at the code to see
what I mean. Here, we are talking about the name "bob".
Second I present below two alternatives (designated "method1" and "method2" in
the comments of the listings below) to a method that resides in a program I
am writing. I run the program with the same python executable with which I
generated the above example. These method listings are long but differ only
where I have indicated in the comments. I am including them in their entirety
so that I don't leave something critical out that I, as a relative novice, am
missing.
With "method1" I get no error and the "ok()" method works as I expect and in
accord with the example above. With "method2" I call "ok()", and when it
prints to stdout I get the following error (after compile, when the program
is being run):
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.3/lib-tk/Tkinter.py", line 1345, in __call__
return self.func(*args)
File "./passerby", line 1378, in ok
print result
UnboundLocalError: local variable 'result' referenced before assignment
So my question is, what is special about what I am doing here? Why does it not
work like the first example I gave with the name bob? Have I found a bug in
python? I should note that "passWindow" is not defined anywhere else but this
method. Also, I should note that "method1" represents a
workaround/alternative, so my program runs just fine. I just want to know
what is going on here to imporve my own understanding. I think if anyone can
give me a satisfactory answer on this one, we should all call them a "real
expert".
Here are the listings I referred to above:
-----
# method1 : works!
def ask_for_password(self, message):
def cancel():
passWindow.destroy()
def ok():
# different : WORKS FINE!
print passWindow.result
pw = passEntry.get()
if len(pw):
# different
passWindow.result = pw
passWindow.destroy()
message = "\n" + message + "\n"
passWindow = Toplevel(self.get_mainWindow())
# different : notice that passWindow is defined for the
# first time in this whole program in the line above
# It is not part of a larger scope!
passWindow.result = None
passWindow.title("passerby - Password Entry")
self.get_mainWindow().deiconify()
passWindow.transient(self.get_mainWindow())
passWindow.geometry("400x180+50+50")
passWindow.resizable(0,0)
passLabel = Label(passWindow, text=message)
passEntry = Entry(passWindow)
passEntry.configure(width=48)
passEntry.config(show="*")
passEntry.bind("<Return>",ok)
cancelButton = Button(passWindow, text="Cancel", command=cancel)
okButton = Button(passWindow, text="OK", command=ok)
passLabel.pack()
passEntry.pack()
cancelButton.pack()
okButton.pack()
passEntry.focus_set()
passWindow.grab_set()
self.get_tk().wait_window(passWindow)
# different
return passWindow.result
-----
# method2 : doesn't work!
def ask_for_password(self, message):
def cancel():
passWindow.destroy()
def ok():
# different : GETS ERROR!
print result
pw = passEntry.get()
if len(pw):
passWindow.result = pw
passWindow.destroy()
message = "\n" + message + "\n"
passWindow = Toplevel(self.get_mainWindow())
# different : notice that passWindow is defined for the
# first time in this whole program in the line above
# It is not part of a larger scope!
result = None
passWindow.title("passerby - Password Entry")
self.get_mainWindow().deiconify()
passWindow.transient(self.get_mainWindow())
passWindow.geometry("400x180+50+50")
passWindow.resizable(0,0)
passLabel = Label(passWindow, text=message)
passEntry = Entry(passWindow)
passEntry.configure(width=48)
passEntry.config(show="*")
passEntry.bind("<Return>",ok)
cancelButton = Button(passWindow, text="Cancel", command=cancel)
okButton = Button(passWindow, text="OK", command=ok)
passLabel.pack()
passEntry.pack()
cancelButton.pack()
okButton.pack()
passEntry.focus_set()
passWindow.grab_set()
self.get_tk().wait_window(passWindow)
# different
return result
--
James Stroud, Ph.D.
UCLA-DOE Institute for Genomics and Proteomics
611 Charles E. Young Dr. S.
MBI 205, UCLA 951570
Los Angeles CA 90095-1570
http://www.jamesstroud.com/
More information about the Python-list
mailing list