更改自定义类(Python)中的对象属性

更改自定义类(Python)中的对象属性,python,oop,attributes,tkinter,Python,Oop,Attributes,Tkinter,我试图通过在python变量的类上调用一个方法来更改它。我的实际代码比下面的要复杂得多,但是下面的代码演示了这个问题。我理解self是指所讨论的类的实例,所以我认为简单地使用self.val=5或其他任何方法都可以。但事实并非如此 我肯定我错过了一些非常明显的东西。我刚刚开始学习Python,这一切看起来都相当简单,我是如何记住多年前的OOP的,但在几个小时尝试了不同的东西和谷歌搜索了各种各样的短语之后,我仍然被卡住了。我正在使用Python 2.7 from Tkinter import *

我试图通过在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()
如果我单击回答、更改、回答,那么我得到的输出是

  • 二,
  • self.val现在7岁了
  • 二,

在定义时计算lambda默认值
listbox.val
。所以如果你使用

lambda myval=listbox.val: callback(myval)
然后,
myval
的默认值永远等于2

相反,你可以使用

b = Button(top, text="answer", 
           command=lambda mybox=listbox: callback(mybox.val))

lambda默认值
listbox.val
在定义时计算。所以如果你使用

lambda myval=listbox.val: callback(myval)
然后,
myval
的默认值永远等于2

相反,你可以使用

b = Button(top, text="answer", 
           command=lambda mybox=listbox: callback(mybox.val))

事实上,变化很好!问题与你的班级无关;是第二个lambda引起的。Python中的默认值在创建函数时计算,而不是在调用函数时计算:
myval
的默认值在创建lambda时绑定到
listbox.val
的值,并且无论
listbox
发生什么情况都不会更改


如果您将lambda更改为类似于
lambda-box=listbox:callback(box.val)
的内容,这些更改将是可见的。

实际上,它的更改很好!问题与你的班级无关;是第二个lambda引起的。Python中的默认值在创建函数时计算,而不是在调用函数时计算:
myval
的默认值在创建lambda时绑定到
listbox.val
的值,并且无论
listbox
发生什么情况都不会更改


如果将lambda更改为类似于
lambda-box=listbox:callback(box.val)
的内容,则更改将可见。

ARGH!这么简单。我认为这与我调用对象的属性有关,因为我在其他地方使用了lambda函数中的变量,这很好。至少我对lambda函数的理解有误(我还没有完全理解),而不是对基本的OOP理论(理论上我确实理解):)谢谢!啊!这么简单。我认为这与我调用对象的属性有关,因为我在其他地方使用了lambda函数中的变量,这很好。至少我对lambda函数的理解有误(我还没有完全理解),而不是对基本的OOP理论(理论上我确实理解):)谢谢!谢谢你和unutbu说的基本上是一样的,但我应该给别人一个接受的答案,而你的回答稍微快一点…谢谢!你和unutbu说的基本上是一样的,但我应该给别人一个公认的答案,而你的回答稍微快一点。。。