namespaces, scoping and variables

Dave Angel davea at ieee.org
Mon Aug 2 15:54:44 EDT 2010


Chris Hare wrote:
> I am having a problem getting around this variable namespace thing.
>
> Consider these code bits
>
> File a.py
> from Tkinter import *
> import a1
>
> def doAgain():
> 	x =1.Net()
> 	x.show("Again!")
>
> root =k()
> root.title("test")
> f =rame(root,bg="Yellow")
> l =utton(root,text="window 1",command=doAgain)
> f.grid()
> l.grid()
> a =
> x =1.Net()
> x.show("window 2")
> if __name__ ="__main__":
> 	root.mainloop()
>
> File a1.py
> from Tkinter import *
>
> class Net:
> 	def __init__(self):
> 		self.window =oplevel()
> 	def show(self,t):		
> 		self.l =abel(self.window,text=t)
> 		self.l.grid()
>                 button =utton(self.window, text="Again")
> 		button.bind("<Button-1>", self.Again)
>                 button2 =utton(self.window, text="Dismiss")
> 		button2.bind("<Button-1>", self.hide)
> 		button.grid()
> 		button2.grid()
> 	def Again(self,event):
> 		x =et()
> 		x.show(a)
> 	def hide(self,event):
> 		self.window.destroy()
>
>
> When I run a.py, it imports a1.py and click on the Again button, I get the error
>
> Exception in Tkinter callback
> Traceback (most recent call last):
>   File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk/Tkinter.py", line 1410, in __call__
>     return self.func(*args)
>   File "/Volumes/Development/py/a1.py", line 17, in Again
>     x.show(a)
> NameError: global name 'a' is not defined
>
> I believe this is the expected behavior.  so my question is this -- how do I tell the code in a1.py about the variable a, which exists in a.py?  Do I have to pass it as part of the function call, or what?  using
>
> global a
>
> in a1.py doesn't change anything.
>
> since I am using SQLite for the disk database, I was thinking I could keep all the "global" variables in an in memory database and just access them when I need to, but other ideas are welcome.
>
> Thanks,
> Chris
>
>
>   
First rule is never have circular referencing between modules.  In other 
words, since a.py imports a1.py, a.py can refer to things in a1.py, but 
never the other way around.  Any time you need to look backwards, find 
another means.

One approach is to create another module c.py as a container to hold 
those things that both a and a1 need.  That way they both import c, and 
there's no problem.

Another approach is to pass the global from a.py into a1.py, and use it 
that way.

And since you only have these two modules, you could just define it in 
a1.py, and reference it from a.py as
   a1.a

I would point out that using the same name for a module and a global 
variable is bad practice.  it certainly makes it hard to describe in 
this case.

HTH,
DaveA



More information about the Python-list mailing list