class Test1: def __init__(self): self.__test = 1 def getvalue(self): return self.__test class Test2(Test1): def __init__(self): Test1.__init__(self) self.__test = 2 test = Test2()
为什么print test.getvalue()返回1?类和私有变量
class Test1: def __init__(self): self.__test = 1 def getvalue(self): return self.__test class Test2(Test1): def __init__(self): Test1.__init__(self) self.__test = 2 test = Test2()
为什么print test.getvalue()返回1?类和私有变量
在Python,私有成员Foo
类的__bar
将automatically renamed到_Foo__bar
,所以在Test1
的__test
是_Test1__test
并且在Test2
是_Test2__test
。这两位成员实际上是不同的。这是设计,到"avoid name clashes of names with names defined by subclasses"。
如果您希望子类能够看到变量,同时仍然不想将其保留为公共接口的一部分,请使用单个下划线_test
。
此行为归因于name mangling for attribute names starting with __
。基本上,__test
内部Test1
内_Test1__test
和_Test2__test
内部Test2
,所以它们是两个不同的属性。
它的工作原理完全一样的方式在其他语言,比如Java(试试吧!)在Python相关问题
class Test1 {
private int test = 1;
public int getValue() {
return test;
}
}
class Test2 extends Test1 {
private int test = 2;
}
public class Test { // Run the test
public static void main(String[] args) {
Test2 t = new Test2();
System.out.println(t.getValue());
}
}
(为什么我张贴的Java代码呢?因为一些评论说“这在任何OO语言中都不起作用“,”这就是为什么你不用私有变量使用名称修饰“ - 与Python相比,Java采用另一种OO方法,并且不使用名称修饰来实现私有变量行为是相同的)
在Test1中声明的方法可以访问Test1的专用变量ES。该方法是否从子类调用不会改变任何内容,除非子类覆盖该方法。并不是私人成员在儿童班中“消失”或“被忽略”。他们仍然存在,可以通过父类的方法访问。
只有当Test2为getvalue()声明自己的实现时,Test1的私有成员将变得不可访问,并且Test2的私有成员将变为可访问。
换句话说,可以说私人成员不是“虚拟的”(或“可覆盖的”)。它们是类和它的方法的实现细节,不应该被覆盖。 Test1.__test
和Test2.__test
是不同的实例变量(通过名称修改在Python中实现)。
如果你想在传统的面向对象的行为,其中一个子类成员重写其母公司,在Python,Java的使用方法,或虚方法在C++,C#,Delphi的; 不是私有属性。如果你想实现没有名字冲突的事情,那么使用私有属性。
这不适用于任何OO语言。如果'Test1'有一个私有变量,'Test2'不能访问它。受保护的变量对其他类隐藏,但暴露给子类。 – unholysampler 2011-05-31 12:04:00
而这**是为什么你不使用名称修改私有变量。 – delnan 2011-05-31 14:44:39