0

我正在尝试通过调用其类上的方法来更改 python 变量。我的实际代码比下面的要复杂得多,但下面演示了这个问题。我知道 self 是指相关类的实例,所以我想简单地使用 self.val = 5 或任何可行的方法。但事实并非如此。

我确定我错过了一些非常明显的东西。我刚刚开始使用 Python 上课,这一切看起来都相当简单,而且我记得很多年前的 OOP,但是经过几个小时尝试不同的事情并在谷歌上搜索各种短语后,我仍然卡住了。我正在使用 Python 2.7。

from Tkinter import *

class mylistbox(Listbox):
    def __init__(self, *args, **kwargs):
        Listbox.__init__(self, *args, **kwargs)
        self.val = 2    # setting val in this instance to 2

    def change(self, newval): #in my real code this method does a lot more
        self.val = newval # this doesn't change val in this instance!
        print "self.val is now " + str(self.val)

def callback(x):
    print x

top = Tk()

listbox = mylistbox(top)
listbox.pack()

b = Button(top, text="change", command = lambda zzz=7: listbox.change(zzz))
b.pack()
b = Button(top, text="answer", command = lambda myval=listbox.val: callback(myval))
b.pack()

top.mainloop()

如果我点击回答、更改、回答,那么我得到的输出是......

  • 2
  • self.val 现在是 7
  • 2
4

2 回答 2

2

lambda 默认值listbox.val在定义时进行评估。所以如果你使用

lambda myval=listbox.val: callback(myval)

thenmyval的默认值永远等于 2。

相反,您可以使用

b = Button(top, text="answer", 
           command=lambda mybox=listbox: callback(mybox.val))
于 2013-09-05T20:25:57.637 回答
2

其实改的挺好的!问题与您的课程无关。这是导致它的第二个 lambda。Python 中的默认值是在创建函数时评估的,而不是在调用它时进行评估:myval的默认值绑定到listbox.val创建 lambda 时的值,并且无论 发生什么都不会改变listbox

如果您将该 lambda 更改为类似lambda box=listbox: callback(box.val)的更改将是可见的。

于 2013-09-05T20:26:35.313 回答