2016-10-09 62 views
1

在Python 2.7.10爲什麼不是所有的基類構造函數都被調用?

class OneMixin(object): 
    def __init__(self): 
     # super(OneMixin, self).__init__() 
     print "one mixin" 

class TwoMixin(object): 
    def __init__(self): 
     # super(TwoMixin, self).__init__() 
     print "two mixin" 

class Account(OneMixin, TwoMixin): 
    def __init__(self): 
     super(Account, self).__init__() 
     print "account" 

的Account.mro()是:[<class 'Account'>, <class 'OneMixin'>, <class 'TwoMixin'>, <type 'object'>]

雖然每個類在MRO列出的,不打印 「兩混入」。

如果我在OneMixin和TwoMixin中取消超級呼叫的註釋,那麼MRO是完全一樣的,但是「兩個mixin」是打印的。

爲什麼區別?我希望MRO的每一件事都能被召喚出來。

回答

1

這是因爲super用於將調用委派給類型的父類或同級類。 Python documentation對第二個用例的描述如下:

第二個用例是支持動態執行環境中的協作多重繼承。這個用例是Python獨有的,在靜態編譯的語言或僅支持單一繼承的語言中找不到。這使得在多個基類實現相同方法的情況下實現「菱形圖」成爲可能。良好的設計規定,這種方法在每種情況下都具有相同的調用簽名(因爲調用順序是在運行時確定的,因爲該順序適用於類層次結構中的更改,並且因爲該順序可以包含運行時未知的同級類)。

如果您從OneMixinsuper通話沒有什麼把調用交給MRO中的下一個類型。

1

原因是你重寫了父類的__init__方法。無論您的方法如何,方法解析順序都是相同的。

工作方式super的工作原理是,它會將它傳遞給下一個類的方法解析順序。通過評論OneMixin中的那一行,你打破了這個鏈條。 super是專爲合作繼承。另外,__init__也不是真正的類構造函數。如果你像其他語言的構造函數一樣考慮它,這可能會讓你感覺不舒服。

相關問題