2015-07-05 29 views
19

3 sınıf sınıf devralma düzeyine sahip bazı kodlarla çalışıyorum. En düşük seviyeli türetilmiş sınıftan, bir yöntemin (2) hiyerarşiyi (ör. Bir super.super çağrı? "Orta" sınıfı, aramam gereken yöntemi uygulamıyor.Süper yöntem nasıl aranır?

+7

Neden böyle ihtiyacım var? Orta sınıftaki yöntemin üzerine yazmış olmadıkça, tek bir süper() çağrı yeterli olmalıdır, bu durumda orta sınıf, super() yöntemini doğru çağırmaya dikkat etmelidir. –

+1

Eğer orta sınıf bu yöntemi uygulamıyorsa, sadece 'super()' ı çağırın. () 'Çalışmalıdır, çünkü miras yoluyla orta sınıfınız süper sınıf –

+0

yöntemlerini miras alır? MRO'da * bir uygulama atlamak mı istiyorsunuz? – jonrsharpe

cevap

34

Eh, bunu yapmanın bir yolu şudur:

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) 

Belki istediğini değil ama yanılmıyorsam iyi piton vardır bu. İstediğin şey, anti-pythonic gibi sesler çıkarır ve niçin yaptığımıza dair bir şey yapmanın mutlu python yöntemini vermemiz gerektiğini açıklamak zorunda kalırsın.

başka örnek, belki (sizin yorumlardan) istediğini: Gördüğünüz gibi

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

, Parentmy_method ama Child hala Parent "gördüğü yönteme ulaşmak için süper kullanabilirsiniz uygulamıyor "Grandparent" my_method.

+0

Zaten iç içe "süper" çağrıları yapabileceğinizi sanmıyorum çünkü tür "süper" olacaktır. –

+0

Benim durumumda, Parent sınıfı my_method'u uygulamıyor ve bunu sadece çocuk aramasını işe almak için eklemek istemiyorum. – SeanLabs

+3

Orta sınıfa ebeveyn sınıfından yöntemler devralmanıza gerek yok, bu yüzden "super(). Method()" ifadesi işe yarayacaktı. –

-2

yukarı iki seviye istiyorsanız, neden sadece

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  

Sen __bases__ boşsa kontrol veya orta sınıflar çoklu kalıtım varsa üzerinde döngü gibi bir şey savunmacı ekleyebilirsiniz yapamaz. Yuvalama süper çalışmıyor çünkü süper tipi üst tip değil.

+0

Asla, * hiç *, EVER, 'super()' içinde 'self .__ class__' kullanın. Üslere bile ulaşma. 'self .__ class__' **, her zaman yöntemi tanımladığınız sınıf değil **, bir alt sınıf olabilir. Başka iki miras kalıntısı eklerseniz, artık sonsuz bir döngüye sahipsiniz. –

-1

Sizin durumunuzda sınıfının işlevinin my_method işlevini çağırması.

Bunu iki yolla statik ve dinamik olarak yapabilirsiniz. Ben 0 endeksini aldı neden

Dinamik İşte

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__) tuple tipi thats A taban sınıfları dönecektir. Böylece B sınıfını B sınıfında süper argüman olarak sınıfının B sınıfının temel sınıfına döndürecektir.

Statik

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

Asla, * hiç *, EVER, 'super()' içinde 'self .__ class__' kullanın. Üslere bile ulaşma. 'self .__ class__' **, her zaman yöntemi tanımladığınız sınıf değil **, bir alt sınıf olabilir. Başka iki miras kalıntısı eklerseniz, artık sonsuz bir döngüye sahipsiniz. –

+1

biraz melodramatik mi? – dopatraman

2

Bu benim için çalışıyor:

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

Bu, muhtemelen doğru cevap olarak işaretlenmesi gereken cevaptır. – nesdis

İlgili konular