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?
Odpowiedz
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
.
Nie sądzę, że możesz wykonywać zagnieżdżone połączenia 'super' mimo to, ponieważ typem byłoby' super'. –
W moim przypadku klasa Parent nie implementuje metody my_method i nie chcę jej dodawać tylko w celu uzyskania wywołania funkcji child. – SeanLabs
Nie musisz, klasa średnia dziedziczy metody z klas nadrzędnych, więc działanie 'super(). Method()' zadziała. –
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.
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ę. –
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
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ę. –
trochę melodramatyczny jesteśmy? – dopatraman
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()
Jest to prawdopodobnie odpowiedź, którą należy oznaczyć jako właściwą odpowiedź – nesdis
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()? –
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 –
Czy masz na myśli, że chcesz * pominąć * implementację w MRO? – jonrsharpe