在尝试使用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的值?
由于
答案 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会查找