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

为何含tkinter与全局变量的Python函数始终返回0?

Tkinter按钮点击返回值异常问题

问题描述

以下代码中,ask2函数无论点击哪个按钮始终返回0,预期点击第一个按钮返回0、点击第二个按钮返回2,请问问题出在哪?

from tkinter import*
root = Tk()
root.title("Example")
root.geometry("1000x250")
root['bg']="black"
def ask2(question,var1,var2):
    ans = 0
    def button1():
        global ans
        bt1.destroy()
        bt2.destroy()
        lb.destroy()
        root.quit()
        ans = 0
    def button2():
        global ans
        bt1.destroy()
        bt2.destroy()
        lb.destroy()
        root.quit()
        ans = 1
    lb = Label(root,text=question,
                bg="black",
                fg="white",
                font=("Determination (RUS BY LYAJKA)",28))
    bt1 = Button(text=var1,
                 justify=CENTER,
                 relief=SOLID,
                 bg="black",
                 fg="white",
                 font=("Determination (RUS BY LYAJKA)",20),
                 command=button1,
                 disabledforeground="yellow")
    bt2 = Button(text=var2,
                 justify=CENTER,
                 relief=SOLID,
                 bg="black",
                 fg="white",
                 font=("Determination (RUS BY LYAJKA)",20),
                 command=button2)
    lb.pack(side=TOP)
    bt1.pack(side=LEFT)
    bt2.pack(side=RIGHT)
    root.mainloop()
    if ans == 0:
        return(0)
    else:
        return(2)    
print(ask2("Question","Answer 1", "Answer 2"))

问题原因

核心问题是global ans的使用错误:

  • ask2函数里的ans是局部变量,但内部嵌套的button1和button2函数用了global声明,这会让它们去修改全局作用域里的ans,而不是ask2里的局部ans。
  • 当root.mainloop()结束后,ask2判断的是自己一开始初始化的局部ans(值为0),所以不管点击哪个按钮,最终都会返回0。

解决方案

可以用两种简单的方式修复:

方法1:用nonlocal代替global

把button1和button2里的global ans改成nonlocal ans,这样就能让嵌套函数修改外层ask2函数的局部变量:

def ask2(question,var1,var2):
    ans = 0
    def button1():
        nonlocal ans  # 替换global为nonlocal
        bt1.destroy()
        bt2.destroy()
        lb.destroy()
        root.quit()
        ans = 0
    def button2():
        nonlocal ans  # 替换global为nonlocal
        bt1.destroy()
        bt2.destroy()
        lb.destroy()
        root.quit()
        ans = 1
    # 后续代码不变...

方法2:用可变对象存储ans(兼容Python2)

如果需要兼容Python2(没有nonlocal),可以用列表这种可变对象来存ans,因为可变对象的修改会影响外层作用域:

def ask2(question,var1,var2):
    ans = [0]  # 用列表存值
    def button1():
        bt1.destroy()
        bt2.destroy()
        lb.destroy()
        root.quit()
        ans[0] = 0  # 修改列表元素
    def button2():
        bt1.destroy()
        bt2.destroy()
        lb.destroy()
        root.quit()
        ans[0] = 1  # 修改列表元素
    # 后续代码不变...
    root.mainloop()
    if ans[0] == 0:  # 取列表元素判断
        return(0)
    else:
        return(2)

这样修改后,点击第一个按钮会返回0,点击第二个按钮返回2,符合预期。

内容的提问来源于stack exchange,提问作者Denis Pasishnichenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:37:04