[Tutor] Question about why a list variable is apparently global.

Steven D'Aprano steve at pearwood.info
Thu Nov 27 01:20:23 CET 2014


On Wed, Nov 26, 2014 at 05:23:40PM -0600, boB Stepp wrote:
> Python 2.4.4
> Solaris 10
> 
> #!/usr/bin/env python
> 
> from Tkinter import *
> 
> def printLabel():
>     print "Button number ", var.get(), " was pressed."
>     print "You selected this option:", l[var.get() - 1][0]
> 
> root = Tk()
> root.title("ROI List Creator")
> root.geometry(newGeometry='225x230+900+300')
> root.tk_setPalette(background='gray')
> 
> buttonNumber = []
> l = [("Brain_Partial", 1), ("Brain_Whole", 2),
>                         ("Head & Neck", 3), ("Chest", 4), ("Breast_Whole", 5),
>                         ("Breast_Partial", 6), ("Abdomen", 7), ("Pelvis", 8),
>                         ("Prostate", 9)]
> var = IntVar()
> for text, value in l:
>     buttonNumber.append(Radiobutton(root, text = text, value = value,
>                     command=printLabel, variable = var).pack(anchor=W))
> var.set(5)
> print "The button's value is: ", var.get()
> root.update()
> print "The geometry info is: ", root.winfo_geometry()
> print "The screen width is: ", root.winfo_screenwidth()
> print "The screen height is: ", root.winfo_screenheight()
> root.mainloop()
> 
> First, I continue to "Easter Egg Hunt" in the sweet land of Python,
> and now Tkinter. So what I actually know is quite a hodgepodge at this
> time.
> 
> The function above, printLabel(), will eventually read a file of names
> anatomical structures based upon the user's radiobutton selection and
> populate those names into a ROI List in our planning software. But for
> now I am mostly focused on designing the small radiobutton window and
> getting it to do what I expect. I am totally new to Tkinter, but it
> seems much more manageable than what our planning software provides
> for scripting GUIs.
> 
> First question: How can the printLabel() function see the list
> variable, l, defined outside of this function? I thought that
> functions only had access to variables local to the function and
> whatever else is passed to it during the function call.

No, they also have access to globals and built-ins. You define the list 
l at the top level of your module. That makes it a global, so the 
printLavel() function can see it.

Note that this principle is critical to Python, otherwise functions 
couldn't call each other, or even built-ins! If you have two functions:

def f(): return g()

def g(): return "Hello!"

"g" is a global "variable" and f() can see it, otherwise it couldn't 
call it. 

I put variable in scare-quotes because it's actually more of a 
pseudo-constant, a constant by convention, since it is very unusual to 
change things you define as a function. To be more precise, the *name* 
"g" which refers to the function exists in the module's global scope. As 
a short-cut, we call such names "global variables", even if they never 
vary.

You only need to declare a global variable inside a function if you are 
re-assigning a value to it. Hence:

a = 1
b = 2
def test():
    global b
    b = b + a

Since you are only fetching the value of global name "a", not assigning 
to it, you don't need to declare it as global.


> Second: Will the statements near the end that return the display
> screen's width and height be a reliable way of determining the user's
> actual monitor settings? 

That's really an issue for tk/tcl, not Python. I would expect they are 
reliable, but tk/tcl have been around for a very, very long time so it 
would be surprising if there were bugs in something as common as getting 
the screen dimensions.



[...]
> Third: I am always open to stylistic comments and how to be more pythonic!

Fix your variable names!

You have a variable called "buttonNumber" which holds a LIST, not a 
number. Confusing!

You have another variable called "1", or is that "I", no sorry it's "l". 
Notice that depending on the font you use, 1 I and l can look almost 
exactly the same. That's a bad thing. Also, the name "l" doesn't mean 
anything, it doesn't tell you the purpose of the variable.

Then there is another variable called "var". That's nice, we already 
know it's a variable, but what role does it play in your program? Try to 
find a more descriptive name. 

> Fourth: And perhaps this should go into a new thread, I am not sure I
> understand the full intent and use of Tkinter's Variable class. Any
> clarification on this would be welcome as well.

Sorry, no clue.


-- 
Steven


More information about the Tutor mailing list