Mindboggling Scope Issue

J

James Stroud

Hello All,

I originally posted this to the help list, but I wanted to try a broader
audience. Its so bizarre, that it may take some discourse to understand what
is going on.

Far below are two alternative methods I have made inside a class. In "method1"
I create a name called "passWindow.result" and use it in the "ok()" function.
In "method2", I simply call this name "result".

Matt Cowles gave this explanation:
The important difference is that you assign to the variable result
later in the function. If a variable isn't assigned to in a function,
Python looks for it in enclosing namespaces:

If I understand Matt's answer, "ask_for_password(self,message)", should be the
enclosing namespace for "ok()". So I am still confused: notice how I defined
"passWindow" on the line preceding the "result=None" (method2) or
"passWindow.result=None" (method1) statments. I haven't defined "passWindow"
before I defined it in the "get_password(self)" method, i.e. "passWindow",
like "result" and "passWindow.result", is not part of the global name space
or any other enclosing namespace beyond the "get_password(self)" method.

Testing Matt's explanation, I began a fresh CLI session (using the same python
executable used for my program). The session is cut and pasted from my
terminal:

% 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 inner():
.... print bob
.... bob = "wuzzup?"
.... inner()
....wuzzup?

This works as I expect and in accord with Matt's explanation and the Laws of
Common Sense, but it appears to be entirely inconsistent with the behavior of
"method2" below. Thus, I am completely bewildered.

I have pasted the methods below (sorry they are so long, but I didn't want
to alter them--maybe clues lie within).

-----

# method1
#####################################################################
# get_password(self)
#####################################################################
def ask_for_password(self, message):
def cancel():
passWindow.destroy()
def ok():
# WORKS FINE!
print passWindow.result
pw = passEntry.get()
if len(pw):
passWindow.result = pw
passWindow.destroy()
message = "\n" + message + "\n"
# make a new top level for the pass window
passWindow = Toplevel(self.get_mainWindow())
passWindow.result = None
# title it something meaningful
passWindow.title("passerby - Password Entry")
# - will use the main view (view #0) to own the password entry
# this will help the user remember what he's doing
# - need to show the main view
self.get_mainWindow().deiconify()
# - set ownership of the passWindow to main view
passWindow.transient(self.get_mainWindow())
# setting the geometry of the passWindow
# pass_x = anEvent.x_root - 50
# pass_y = anEvent.y_root - 50
passWindow.geometry("400x180+50+50")
# - don't let user change our beautiful window
passWindow.resizable(0,0)
# the entry label and field
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)
return passWindow.result

-----

# method2
#####################################################################
# get_password(self)
#####################################################################
def ask_for_password(self, message):
def cancel():
passWindow.destroy()
def ok():
# GETS ERROR!
print result
pw = passEntry.get()
if len(pw):
passWindow.result = pw
passWindow.destroy()
message = "\n" + message + "\n"
# make a new top level for the pass window
passWindow = Toplevel(self.get_mainWindow())
result = None
# title it something meaningful
passWindow.title("passerby - Password Entry")
# - will use the main view (view #0) to own the password entry
# this will help the user remember what he's doing
# - need to show the main view
self.get_mainWindow().deiconify()
# - set ownership of the passWindow to main view
passWindow.transient(self.get_mainWindow())
# setting the geometry of the passWindow
# pass_x = anEvent.x_root - 50
# pass_y = anEvent.y_root - 50
passWindow.geometry("400x180+50+50")
# - don't let user change our beautiful window
passWindow.resizable(0,0)
# the entry label and field
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)
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/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,252
Latest member
MeredithPl

Latest Threads

Top