Mindboggling Scope Issue
James Stroud
jstroud at mbi.ucla.edu
Sun Oct 24 19:18:58 EDT 2004
I just realized that I spelled Terry Reedy's name wrong in my previous email.
My apologies to Terry.
James
On Sunday 24 October 2004 04:16 pm, James Stroud wrote:
> 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/
--
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