2013-12-08 99 views
10

所以,我有這樣的情況。Python調用父方法多繼承

class A(object): 
    def foo(self, call_from): 
     print "foo from A, call from %s" % call_from 


class B(object): 
    def foo(self, call_from): 
     print "foo from B, call from %s" % call_from 


class C(object): 
    def foo(self, call_from): 
     print "foo from C, call from %s" % call_from 


class D(A, B, C): 
    def foo(self): 
     print "foo from D" 
     super(D, self).foo("D") 

d = D() 
d.foo() 

代碼的結果是

foo from D 
foo from A, call from D 

我想打電話給所有的父類的方法,在這種情況下,FOO的方法,從D課,而不會在諸如A父類使用超。我只想打電話給D這個班。 A,BC類就像mixin類,我想調用D的所有foo方法。我怎樣才能做到這一點?

回答

7

您可以使用__bases__這樣

class D(A, B, C): 
    def foo(self): 
     print "foo from D" 
     for cls in D.__bases__: 
      cls().foo("D") 

隨着這一變化,輸出將是

foo from D 
foo from A, call from D 
foo from B, call from D 
foo from C, call from D 
+0

這是一個有點粗略的......如果你現在有兩個類都從D繼承,然後從這兩個繼承另一個類?現在'foo'會調用'A.foo'兩次。 – mgilson

+1

或者如果'B.foo'不存在會發生什麼?最後,我認爲它應該是'cls.foo(self)',而不是'cls()。foo()' – mgilson

+0

@mgilson然後,我們必須使用'mro'?那些不是階級方法,對嗎?所以,我不得不創建對象來調用它們。 – thefourtheye

8

添加super()呼叫的其他類以及除了C。由於D的MRO是

>>> D.__mro__ 
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <type 'object'>) 

你不需要超級呼叫C

代碼:

class A(object): 
    def foo(self, call_from): 
     print "foo from A, call from %s" % call_from 
     super(A,self).foo('A') 

class B(object): 
    def foo(self, call_from): 
     print "foo from B, call from %s" % call_from 
     super(B, self).foo('B') 


class C(object): 
    def foo(self, call_from): 
     print "foo from C, call from %s" % call_from 

class D(A, B, C): 
    def foo(self): 
     print "foo from D" 
     super(D, self).foo("D") 

d = D() 
d.foo() 

輸出:

foo from D 
foo from A, call from D 
foo from B, call from A 
foo from C, call from B 
+0

如果你不明白我的描述,我想調用所有'foo'方法,而不用像'A'或'B'或'C'那樣在父類中調用super。 –

+1

@EdwinLunando - 我認爲這並不是如此。爲了超級正常工作,所有類都需要使用它。 [參見關於將超級方法與非超級方法混合的部分](https://fuhm.net/super-harmful/)。 – mgilson

+0

@EdwinLunando然後遍歷'__mro__'或'__bases__'並顯式地調用每個類,但是然後**不能在'D'中使用**'super'。 –