为什么在父类中更改'x'的值只会更改一个子项的值?

时间:2015-11-26 11:36:07

标签: python class inheritance theory

在尝试使用python时,我意识到这段代码不会产生我期望的输出:

class Parent(object):
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass


print Parent.x, Child1.x, Child2.x

Child1.x = 2
print Parent.x, Child1.x, Child2.x

Parent.x = 3
print Parent.x, Child1.x, Child2.x

上述代码的输出是:

1 1 1
1 2 1
3 2 3

为什么最后一行3 2 3而不是3 2 1的输出?为什么更改Parent.x的值也会更改Child2.x的值,但同时不会更改Child1.x的值?

由于

3 个答案:

答案 0 :(得分:4)

当您分配到Child1.x时,您仅为Child1创建了一个新属性。但是,Child2没有自己的x属性,所以它继承了Parent的版本,无论当前的值是什么。

答案 1 :(得分:1)

就类中定义的属性而言,Python具有写时复制行为。由于Python中的每个变量都是引用,因此在您为Child1.x分配新值之前,x中的Child1指的是Parent.x的值。

事实上你正在尝试做的事情一般都是不好的做法!你不应该放置你计划稍后修改的类定义变量,直到你真的知道你正在做什么。事实上,您的示例是面向对象范例的滥用,因为您应该使用类的实例,而不是类本身。

答案 2 :(得分:1)

评论中更广泛的答案 如果你将它添加到脚本的末尾

print Parent.__dict__
print Child1.__dict__
print Child2.__dict__

您可以详细了解班级中的所有成员以及存储在其中的内容。 输出将是

{'__dict__': <attribute '__dict__' of 'Parent' objects>, 'x': 3,    '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Parent' objects>, '__doc__': None}
{'x': 2, '__module__': '__main__', '__doc__': None}
{'__module__': '__main__', '__doc__': None}

正如你在child1中看到的那样 'x':2 被添加到字典中。所以child1不会在它的父类中查找值,但是child2会查找