2013-09-16 80 views
3

我不理解“自我”的对象在以下Python代码:什么是Python中的“Self”对象?

>>> class Ancestor(object): 
    def __init__(self): 
     self.name = "Ancestor" 
    def getName(self): 
     return self.name 


>>> class Base1(Ancestor): 
    def __init__(self): 
     self.name = "Base1" 
     super(Base1, self).__init__() 
    def getName(self): 
     return self.name 


>>> class Base2(Base1): 
    def __init__(self): 
     self.name = "Base2" 
     super(Base2, self).__init__() 
    def getName(self): 
     return self.name 
    def getB1Name(self): 
     return super(Base2, self).getName() 


>>> b2 = Base2() 
>>> b2.getName() 
'Ancestor' 
>>> b2.getB1Name() 
'Ancestor' 

我无法理解的结果。我期待b2.getName()的结果为“Base2”,并且b2.getB1Name()的结果为“Base1”

回答

3

self指的是实例,而不是类。你只有一个实例,所以self的所有用法都指向同一个对象。在Base2.__init__中,您为此对象设置了一个名称。然后调用super,调用Base1.__init__,它在同一个对象上设置一个新名称,覆盖旧名称。

如果您真的需要,您可以使用double-underscore attributes来达到您想要的效果。

+0

谢谢,那是我正在寻找的解释 –

4

当您调用super函数时,您基本上跳入了构造函数Ancestor类并在那里执行代码。在构造函数中,将名称设置为"Ancestor",覆盖基类中的新名称。

如果您致电super每个构造函数的第一行,它应该返回正确的名称。


但是,请注意,B2getB1Name函数总是返回字符串"Base2" - 的name变量只是覆盖,以任何方式不是“阴影”。

可以使用双下划线变量,使“阴影”的行为被保留,它会自动做一些名称忙玲,但在一般情况下,一个更清洁的解决方案是简单地使用不同的变量名,和设计代码,以便不需要浮动的相同属性的两个不同版本。

+2

把呼叫放到'超级'首先仍然不会做他期望的。无论按照什么顺序调用方法,如果您使用'self',则只会为该属性获取一个值。它可以是层次结构中的最低层或最高层,但根据所调用的方法,您不会得到不同的值。 – BrenBarn

+0

是的,是的。起初我没有看到额外的方法 - 我主要看的是构造函数。 – Michael0x2a

相关问题