Python全局变量在Tkinter循环中修改后恢复初始值问题求助
问题描述
我正在编写一个Python程序,用于在网页状态变化时发送提示信息。当前使用Tkinter构建窗口并运行循环,已声明全局变量,但在循环内修改全局变量后,下一轮循环中变量会恢复为初始值。
简化后的代码如下:
# just variables (i have simplified the code) aux1 = False aux2 = False aux3 = False def search(url, aux): try: host_get = request.get(ip) if host_get.status_code == 200: host_cont = host_get.text host_soup = BeautifulSoup(host_cont, 'lxml') try: host_stat = host_soup.find('div', class_='UP').getText() aux = False except: if aux == False: MessageBox.showWarning("Alert", "Host is DOWN") aux = True # The problem is here # After doing this (aux = True), the program still doing (aux = False) options elif aux == True: print("Host still DOWN") else: MessageBox.showWarning("Alert", "Host is DOWN") aux = True def search_loop(): # i have many websites, but i showed only 1 for the example code url1 = "website1.com" global aux1 search(url1, aux1) # 5 seconds to do the next loop time.sleep(5) class WindowClass: def __init__(self): self.window1 = tk.Tk() self.button1() self.window1.mainloop() def button1(self): self.startbutton = tk.Button(self.window1, command=self.startloop, text='Start') self.startbutton.place(x=50, y=50) def startloop(self): search_loop() app1 = WindowClass()
问题表现为:将aux设为True后,程序仍会执行aux为False时的逻辑,希望得到解决方法。
问题原因
- 参数传递问题:布尔值是Python不可变类型,函数内的
aux = True只是修改了局部变量的引用,不会同步到外部的全局变量aux1。即便search_loop声明了global aux1,也只是把aux1的值传给search,函数内的修改不会影响全局变量。 - 主循环阻塞:
time.sleep(5)会卡死Tkinter主界面,同时导致循环无法正确按预期执行。 - 代码中还存在几处语法错误:
request.get应为requests.get、class='UP'.getText()语法错误、MessageBox.showWarning应为小写showwarning。
解决方法
方案一:直接操作全局变量
修改search函数,通过变量名直接读写全局变量,避免参数传递的问题:
import tkinter as tk from tkinter import messagebox as MessageBox import requests from bs4 import BeautifulSoup aux1 = False aux2 = False aux3 = False def search(url, aux_name): # 通过变量名获取全局变量当前值 current_aux = globals()[aux_name] try: host_get = requests.get(url) if host_get.status_code == 200: host_cont = host_get.text host_soup = BeautifulSoup(host_cont, 'lxml') # 尝试查找UP状态元素 host_soup.find('div', class_='UP').getText() globals()[aux_name] = False else: if not current_aux: MessageBox.showwarning("Alert", "Host is DOWN") globals()[aux_name] = True else: print("Host still DOWN") except Exception as e: # 请求失败或元素查找失败,判定为DOWN if not current_aux: MessageBox.showwarning("Alert", "Host is DOWN") globals()[aux_name] = True else: print("Host still DOWN") def search_loop(): url1 = "website1.com" search(url1, "aux1") # 用Tkinter的after方法替代sleep,避免阻塞主循环 root.after(5000, search_loop) class WindowClass: def __init__(self): self.window1 = tk.Tk() global root root = self.window1 self.button1() self.window1.mainloop() def button1(self): self.startbutton = tk.Button(self.window1, command=self.startloop, text='Start') self.startbutton.place(x=50, y=50) def startloop(self): search_loop() app1 = WindowClass()
方案二:用字典统一管理状态(推荐)
避免全局变量分散,用字典存储所有主机的状态,更易维护:
import tkinter as tk from tkinter import messagebox as MessageBox import requests from bs4 import BeautifulSoup # 统一存储所有主机的状态 host_status = { "website1.com": False, "website2.com": False, "website3.com": False } def search(url): current_status = host_status[url] try: host_get = requests.get(url) if host_get.status_code == 200: host_cont = host_get.text host_soup = BeautifulSoup(host_cont, 'lxml') host_soup.find('div', class_='UP').getText() host_status[url] = False else: if not current_status: MessageBox.showwarning("Alert", f"Host {url} is DOWN") host_status[url] = True else: print(f"Host {url} still DOWN") except Exception as e: if not current_status: MessageBox.showwarning("Alert", f"Host {url} is DOWN") host_status[url] = True else: print(f"Host {url} still DOWN") def search_loop(): for url in host_status.keys(): search(url) root.after(5000, search_loop) class WindowClass: def __init__(self): self.window1 = tk.Tk() global root root = self.window1 self.button1() self.window1.mainloop() def button1(self): self.startbutton = tk.Button(self.window1, command=self.startloop, text='Start') self.startbutton.place(x=50, y=50) def startloop(self): search_loop() app1 = WindowClass()
内容的提问来源于stack exchange,提问作者PyMA
相关产品推荐
相关产品推荐

