在Python中使用全局变量
我正在使用Tkinter来帮助我构建一个FTP客户端。在这个客户端中,我想从一个tk列表框中获取选中的信息。所以我有一个按钮来开始下载,但不管是什么原因,它总是弹出一个错误。
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__
return self.func(*args)
File "/Volumes/LEGO FLASH/ftp.py", line 23, in Download
filename = stuff
NameError: global name 'stuff' is not defined"
下面是我写的代码,供你查看:
# Import the FTP object from ftplib
from ftplib import FTP
from Tkinter import *
import os
app = Tk()
app.title("FTP")
app.geometry("300x300")
lines = []
#[lines.replace(",", "\n")for lines in lines]
#lines = lines.replace(',','\n')
def handleDownload(block):
file.write(block)
print ".",
def append_line(line):
lines.append(line)
#This is where I am caught------->
def Download():
filename = stuff
file = open(filename, 'wb')
ftp.retrbinary('RETR ' + filename, handleDownload)
ftp.close()
def login():
try:
ftp.login(username.get(),password.get())
except:
error = Label(app, text = "Invalid USERNAME OR PASSWORD")
label2 = Label(app, text = "Welcome to Steam Engine").pack()
username.forget()
password.forget()
button.forget()
app.geometry("800x500")
download = Button(app, text = "Download!!!!!", command = Download)
download.pack(side = "left", pady = "5")
scrollBar.pack(fill = Y, side = "right", padx = "2")
#ftp.cwd('The_Store')
stuff = Listbox(app, height = "700", width = "500")
ftp.retrlines('NLST', append_line)
for i in lines:
stuff.insert(END, i)
stuff.pack(padx = "10", pady = "10")
stuff.config(yscrollcommand = scrollBar.set)
scrollBar.config(command = stuff.yview)
ftp = FTP('sciphigames.com')
label = Label(app, text = "Login").pack(pady = "10")
scrollBar = Scrollbar(app)
username = StringVar(None)
username = Entry(app, text = "Username: ")
username.pack(pady = "2")
password = StringVar(None)
password = Entry(app, text = "Password: ")
password.pack(pady = "2")
button = Button(app, text = "Login!", command = login)
button.pack(pady = "10")
app.mainloop()
任何帮助都会很感激!
谢谢!
3 个回答
0
你只需要在变量前面加上“global”这个词就可以了。
global var1
1
#This is where I am caught------->
def Download():
filename = stuff
这里的 stuff
是什么呢?它不是一个全局变量,看起来像是 login
方法的一个参数,但并不是 Download
方法的参数。
如果你想把 stuff
变成一个全局变量(虽然这可能不是最好的选择),可以使用 global 语句。
# Import the FTP object from ftplib
from ftplib import FTP
from Tkinter import *
import os
# define the global stuff
global stuff
...
def Download():
global stuff
filename = stuff
...
处理这个问题的更好方法是把这些内容放在一个对象里。
class NetworkApp(object):
def login(self):
# here put all the previous code of login
# here we change the callback to self.Download
download = Button(app, text = "Download!!!!!", command = self.Download)
# here we're creating a stuff member
self.stuff = Listbox(app, height = "700", width = "500")
def Download(self):
filename = self.stuff # here we use the stuff member
file = open(filename, 'wb')
ftp.retrbinary('RETR ' + filename, handleDownload)
ftp.close()
#...
net_app = NetworkApp()
button = Button(app, text = "Login!", command = net_app.login)
0
我不太确定你这个 stuff
变量的具体用途,但你遇到的问题可能和你使用它的方式有关。
首先,你把它当作参数传给了 login
函数(顺便说一下,这个函数其实不应该接收任何参数)。你在 login
函数里给这个变量赋值,而在你的 Download
函数里又用到了同名的另一个变量。
再次强调,我不太明白你想用 stuff
变量做什么,但我建议你可以试试下面这样的写法:
.....
app.geometry("300x300")
stuff = None # <<<<----
lines = []
.....
#This is where I am caught------->
def Download():
global stuff # <<<<----
filename = stuff
......
ftp.close()
def login():
global stuff # <<<<----
......
stuff = Listbox(app, height = "700", width = "500")
ftp.retrlines('NLST', append_line)
for i in lines:
stuff.insert(END, i)
stuff.pack(padx = "10", pady = "10")
stuff.config(yscrollcommand = scrollBar.set)
scrollBar.config(command = stuff.yview)
......