考虑我的简单课程
class stud():
def __init__(self,a,b):
self.name=a
self.mark=b
self.message=self.name + ' ' +str(self.mark)
s1=stud('student1',40)
print s1.message --->output=student1 40
s1.name='student2'
print s1.message ----> output =student1 40 , but i expected student2 40
我的问题是为什么当我打印self.message [在修改对象的name属性之后],它打印旧的值?我知道 init 方法在对象创建期间只调用一次,并且name属性设置为value' student1'那时候。但是,我正在改变下一行,再次打印self.message不应该列出新值?
为什么这个self.message没有更新修改后的值?
答案 0 :(得分:5)
跟踪执行情况。
s1=stud('student1',40)
这设置
s1.name
至"student1"
s1.mark
至40 s1.message
至"student1 40"
将属性值视为方框。三个盒子中的每一个都有一个值。其中两个拿着弦。其中一人持有一个号码。他们将保留这些值,直到明确指定它们为止。特别是属性消息没有IDEA如何获得其值。它不知道它通过连接name
属性和mark
属性来获得它的价值。它只知道它的值是"student1 40"
。
print s1.message
这会输出student1 40
(毫不奇怪)
s1.name='student2'
您更新了三个属性中的一个。但你没有更新其他人。
print s1.message
由于您从未明确更改s1.message
,因此仍会输出student1 40
。
关键是s1.message
的值只是一个字符串。没有看不见的计算,只要初始化它的表达式发生变化,它就会自动更新它。其他语言也许就这样工作,但Python却没有。
如果您想要该行为,请执行以下操作:
class stud():
def __init__(self,a,b):
self.name=a
self.mark=b
@property
def message():
return self.name + ' ' +str(self.mark)
答案 1 :(得分:3)
这是因为您初始化了self.message
中的init
,当您s1.name = student2
时,您只更改了self.name
,而self.message
则是self.message
已初始化。
如果您想获得class stud():
def __init__(self,a,b):
self.name=a
self.mark=b
def the_message(self):
self.message = self.name + ' ' + str(self.mark)
return self.message
s1 = stud('student1',40)
print s1.the_message()
s1.name='student2'
print s1.the_message()
,则需要以某种方式更新其值。
什么会起作用:
student1 40
student2 40
输出:
S -> aSb
S -> c
S -> dA
A -> Sd
答案 2 :(得分:2)
当您调用构造函数时,它会初始化name
,mark
和message
。
如果修改name
,则不调用构造函数,因此消息不会更新。
不再调用此语句:
self.message=self.name + ' ' +str(self.mark)
为此,您需要一个函数或属性来在每次需要时计算消息。
def get_message(self):
return self.name + ' ' + str(self.mark)
s1 = Stud('student1', 40)
print(s1.message)
s1.name = 'student2'
print(s1.get_message())
要使用属性,您需要继承object
(因为此功能仅适用于Python 2中的新样式类)。
你可以这样做:
class Stud(object):
def __init__(self, a, b):
self.name = a
self.mark = b
@property
def message(self):
return self.name + ' ' + str(self.mark)
s1 = Stud('student1', 40)
print(s1.message)
s1.name = 'student2'
print(s1.message)
关于代码风格的注意事项:
答案 3 :(得分:1)
因为您只更改了name
属性而不是message
所以它仍然会打印相同的消息。
您需要将message
定义为function
而不是attribute
。继续尝试吧。