2015-07-05 19 views
19

Pracuję z pewnym kodem, który ma 3 poziomy dziedziczenia klasy. Z klasy pochodnej najniższego poziomu, jaka jest składnia wywołania metody 2, znajduje się wyżej w hierarchii, np. połączenie super.super? Klasa "środkowa" nie implementuje metody, którą muszę wywołać.Jak wywołać metodę super?

+7

Dlaczego trzeba, że? Jedno wywołanie 'super()' powinno wystarczyć, chyba że nadpisałeś metodę w klasie średniej, w którym to przypadku klasa średnia powinna zadbać o prawidłowe wywołanie metody super()? –

+1

Jeśli klasa średnia nie implementuje tej metody, po prostu wywołaj 'super(). () 'powinno działać, ponieważ dziedziczenie twoja klasa średnia odziedziczyłaby metody z super klasy –

+0

Czy masz na myśli, że chcesz * pominąć * implementację w MRO? – jonrsharpe

Odpowiedz

34

Cóż, jest to jeden ze sposobów go:

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) 

Może nie to, co chcesz, ale to najlepszy python ma chyba że jestem w błędzie. To, o co prosisz, brzmi "anty-pytonowo" i musiałbyś wytłumaczyć, dlaczego robisz to dla nas, by dać ci radosny sposób pisania pythona.

Innym przykładem, może być to, co chcesz (od twoich komentarzach):

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() 

Jak widać, Parent nie implementuje my_method ale Child mogą nadal korzystać z Super dostać na metodzie, która Parent „widzi ", czyli Grandparent 's my_method.

+0

Nie sądzę, że możesz wykonywać zagnieżdżone połączenia 'super' mimo to, ponieważ typem byłoby' super'. –

+0

W moim przypadku klasa Parent nie implementuje metody my_method i nie chcę jej dodawać tylko w celu uzyskania wywołania funkcji child. – SeanLabs

+3

Nie musisz, klasa średnia dziedziczy metody z klas nadrzędnych, więc działanie 'super(). Method()' zadziała. –

-2

Jeśli chcesz dwa poziomy w górę, dlaczego po prostu nie zrobić

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  

Można dodać coś obronne jak sprawdzenie czy __bases__ jest pusta lub zapętlenie nad nim, jeśli klasa średnia mają wielokrotne dziedziczenie. Zagnieżdżanie super nie działa, ponieważ typ super nie jest typem nadrzędnym.

+0

Nigdy, * nigdy *, NIGDY nie używaj 'self .__ class__' w' super() '. Nawet nie dostać się do baz. 'self .__ class__' to ** nie zawsze jest klasą, na której zdefiniowano metodę **, może to być podklasa. Jeśli dodasz kolejne dwa poziomy dziedziczenia, masz teraz nieskończoną pętlę. –

-1

W twoim przypadku, jak zadzwonić my_method funkcja klasy C z A.

Możesz to zrobić na dwa sposoby statycznie i dynamicznie.

Dynamicznie

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() 

Tutaj (self.__class__.__bases__) zwróci klas bazowych A w typie ów krotka dlaczego wziąłem indeks 0TH. Zwraca więc klasę B, więc mając klasę B jako argument w super zwróci ona my_method funkcję klasy bazowej klasy B.

statycznie

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

Nigdy, * nigdy *, NIGDY nie używaj 'self .__ class__' w' super() '. Nawet nie dostać się do baz. 'self .__ class__' to ** nie zawsze jest klasą, na której zdefiniowano metodę **, może to być podklasa. Jeśli dodasz kolejne dwa poziomy dziedziczenia, masz teraz nieskończoną pętlę. –

+1

trochę melodramatyczny jesteśmy? – dopatraman

2

Działa to dla mnie:

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

Jest to prawdopodobnie odpowiedź, którą należy oznaczyć jako właściwą odpowiedź – nesdis

Powiązane problemy