在python类中更新了对象的属性,但没有反映出来

时间:2017-12-30 08:31:19

标签: python oop

考虑我的简单课程

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没有更新修改后的值?

4 个答案:

答案 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)

当您调用构造函数时,它会初始化namemarkmessage

如果修改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)

关于代码风格的注意事项:

  • 类名应该在CamelCase中,
  • 变量和函数名称应为snake_case。

答案 3 :(得分:1)

因为您只更改了name属性而不是message所以它仍然会打印相同的消息。

您需要将message定义为function而不是attribute。继续尝试吧。