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