2015-07-05 81 views
19

我正在使用一些有3個級別繼承的代碼。從最底層的派生類中,在層次結構上調用方法2層的語法是什麼,例如,一個super.super電話? 「中間」類沒有實現我需要調用的方法。如何調用超級方法?

+7

爲什麼你需要嗎?除非你重寫了中間類的方法,否則一個'super()'調用就足夠了,在這種情況下,中間類應該照顧調用super()的方法嗎? –

+1

如果中間類沒有實現該方法,只需調用'super()。 ()'它應該工作,因爲通過繼承你的中產階級會繼承超類的方法 –

+0

你的意思是你想跳過MRO中的一個實現嗎? – jonrsharpe

回答

34

好了,這是做的一種方式:

class Grandparent(object): 
    def my_method(self): 
     print "Grandparent" 

class Parent(Grandparent): 
    def my_method(self): 
     print "Parent" 

class Child(Parent): 
    def my_method(self): 
     print "Hello Grandparent" 
     Grandparent.my_method(self) 

也許不是你想要的,但它是最好的Python有除非我錯了。你所要求的聽起來是反pythonic,你必須解釋你爲什麼要這樣做,讓我們爲你提供快樂的Python方法。

另一個例子,也許你想要什麼(從您的意見):

class Grandparent(object): 
    def my_method(self): 
     print "Grandparent" 

class Parent(Grandparent): 
    def some_other_method(self): 
     print "Parent" 

class Child(Parent): 
    def my_method(self): 
     print "Hello Grandparent" 
     super(Child, self).my_method() 

正如你所看到的,Parent沒有實現my_methodChild仍然可以使用超級拿到那個Parent「看到法「,即Grandparentmy_method

+0

我不認爲你可以做任何嵌套的「超級」調用,因爲類型將是「超級」。 –

+0

在我的情況下,父類沒有實現my_method,我不想爲了讓子調用起作用而添加它。 – SeanLabs

+3

你不需要,中間類繼承父類的方法,所以'super()。method()'會起作用。 –

-2

如果你想向上兩級,爲什麼不只是做

class GrandParent(object):              

    def act(self):                
     print 'grandpa act'              

class Parent(GrandParent):              

    def act(self):                
     print 'parent act'              

class Child(Parent):                

    def act(self):                
     super(Child.__bases__[0], self).act()          
     print 'child act'               


instance = Child()                
instance.act() 

# Prints out 
# >>> grandpa act 
# >>> child act  

您可以添加一些防守像檢查,如果__bases__是空的或循環超過它,如果你的中產階級有多重繼承。嵌套超級不起作用,因爲super的類型不是父類型。

+0

Never,* ever *,EVER在'super()'中使用'self .__ class__'。甚至沒有得到基地。 'self .__ class__'是**並不總是您定義方法**的類,它可以是一個子類。如果您添加另外兩個級別的繼承,則您現在具有無限循環。 –

-1

在你的情況如何呼叫my_method功能CA

您可以通過靜態和動態兩種方式來實現。

動態

class C(object): 
    def my_method(self): 
     print "in function c" 

class B(C): 
    def my_method(self): 
     print "in function b" 

class A(B): 
    def my_method(self): 
     # Call my_method from B 
     super(A, self).my_method() 
     # This is how you can call my_method from C here ? 
     super((self.__class__.__bases__)[0], self).my_method() 
obj_a = A() 
obj_a.my_method() 

這裏(self.__class__.__bases__)將返回A基類中的元組類型這就是爲什麼我把第0指數。所以它返回類B所以有B類作爲參數在超級它將返回my_method基類B類的功能。

靜態

class C(object): 
    def my_method(self): 
     print "in function c" 

class B(C): 
    def my_method(self): 
     print "in function b" 

class A(B): 
    def my_method(self): 
     # Call my_method from B 
     super(A, self).my_method() 
     # This is how you can call my_method from C here ? 
obj_a = A() 
super(A, obj_a).my_method() # calls function of class B 
super(B, obj_a).my_method() # calls function of class C 
+1

Never,* ever *,EVER在'super()'中使用'self .__ class__'。甚至沒有得到基地。 'self .__ class__'是**並不總是您定義方法**的類,它可以是一個子類。如果您添加另外兩個級別的繼承,則您現在具有無限循環。 –

+1

我們有點情緒化嗎? – dopatraman

2

這個工作對我來說:

class Grandparent(object): 
    def my_method(self): 
     print "Grandparent" 

class Parent(Grandparent): 
    def my_method(self): 
     print "Parent" 

class Child(Parent): 
    def my_method(self): 
     print "Hello Grandparent" 
     super(Parent, self).my_method() 
+0

這可能是必須標記爲正確答案的答案 – nesdis