2013-09-16 30 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

相關問題