You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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时的逻辑,希望得到解决方法。


问题原因
  1. 参数传递问题:布尔值是Python不可变类型,函数内的aux = True只是修改了局部变量的引用,不会同步到外部的全局变量aux1。即便search_loop声明了global aux1,也只是把aux1的值传给search,函数内的修改不会影响全局变量。
  2. 主循环阻塞:time.sleep(5)会卡死Tkinter主界面,同时导致循环无法正确按预期执行。
  3. 代码中还存在几处语法错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:11:26