2013-10-15 88 views
0

假設我有一個基類,其中__flag屬性可由@classmethod訪問。Python - 重新定義派生類中的類屬性

class Base(object): 
    __flag = None 

    def __init__(self) : 
     pass 

    @classmethod 
    def flag(self): 
     return self.__flag 

假設我也有一個派生類,在那裏我改變了屬性。

class Derived(Base): 
    __flag = True 

然後,當我嘗試訪問派生類的屬性,我得到的基類的屬性:

In [3]: print Derived.flag() 
None 

爲什麼?我真的不明白。

回答

2

__flag中刪除__,它會很好地工作。像這樣:

class Base(object): 
    flagAtt = None 

    def __init__(self) : 
     pass 

    @classmethod 
    def flag(self): 
     return self.flagAtt 

class Derived(Base): 
    flagAtt = True 

其中給出:

>>> print Derived.flag() 
True 
>>> print Base.flag() 
None 
+0

哦,就這麼簡單!非常感謝你! –

+0

不用擔心男人:) –

3

這是因爲在Python中 「隱藏」 的變量獲得存儲方式不同。那裏有一點魔力。

這就是爲什麼它不工作的例子:

class Base(object): 
    __flag = 'base' 
    _other_flag = 'base' 

    def __init__(self) : 
     pass 

    @classmethod 
    def flag(self): 
     return self.__flag 

    @classmethod 
    def other_flag(self): 
     return self._other_flag 

class Derived(Base): 
    __flag = 'derived' 
    _other_flag = 'derived' 

print 'base flag', Base.flag() 
print 'derived flag', Derived.flag() 
print 'base other flag', Base.other_flag() 
print 'derived other flag', Derived.other_flag() 

# Note the following 2 statements: 
print 'base flag property', Derived._Base__flag 
print 'derived flag property', Derived._Derived__flag 

print 'base other flag property', Base._other_flag 
print 'derived other flag property', Derived._other_flag 

正如你可以在底部看到,它是存儲在一個不同的變量,默默地翻譯成該Base.flag方法中。

1

的Python執行對與兩個下劃線(除了那些端以兩個下劃線),所以在__flagBase__flag不同啓動變量名 - 截斷。您可以通過使用dir觀察此:

>>> class Base(object): 
...  __flag = True 
... 
>>> dir(Base) 
['_Base__flag', '__class__', '__delattr__', ...... # lots of others 

__flag變量變成_Base__flag這裏。在Derived它變成_Derived__flag,所以你實際上並沒有重寫任何東西,只是引入了一個新的變量。

如果你想要一個變量被覆蓋,做而不是使用名稱凝視兩個下劃線。