2013-01-07 28 views
33

Python'da, hangi Parent yönteminin çağrılacağını nasıl seçerim? ASDF2'nin __init__ yöntemini çağırmak istediğimi söyle. Super() .. ASDF1 belirtmek zorunda gibi görünüyor? Ve eğer ASDF3'ün __init__ numarasını aramak istersem, ASDF2?Python'un Çoklu Kalıtım: hangi super() öğesini çağırmak

>>> class ASDF(ASDF1, ASDF2, ASDF3): 
    def __init__(self): 
     super(ASDF1, self).__init__() 


>>> ASDF() 
ASDF2's __init__ happened 
>>> class ASDF(ASDF1, ASDF2, ASDF3): 
    def __init__(self): 
     super(ASDF2, self).__init__() 


>>> ASDF() 
ASDF3's __init__ happened 

Korsanlar bana benziyor. Neyi yanlış yapıyorum?

cevap

47

super() bunun için uygun değildir. Super temel olarak ebeveynlerinden birinin (veya hepsinin) belirli bir sırayla seçilmesini sağlar. Yalnızca tek bir ebeveynin yöntemini çağırmak istiyorsanız, bu

class ASDF(ASDF1, ASDF2, ASDF3): 
    def __init__(self): 
     ASDF2.__init__(self) 
10

super yöntem çözünürlüğü sırayla sonraki yöntemini çağırır yapmak. Doğrusal bir miras ağacında, bu, hemen ana sınıftan bir yöntem olacaktır.

Burada, üç ebeveyne sahipsiniz ve ASDF1 bakış açısından sonraki __init__ yönteminin ASDF2. Genel olarak, güvenli bir şey, neden başka bir şey yapmak istediğinizi bilmedikçe, miras listesindeki birinci sınıfı super'a aktarmaktır.

Tüm bunların amacı, hangi __init__ yöntemlerinin çağrılacağını açıkça belirlemenizdir. Buradaki soru, tüm süper sınıfı __init__ yöntemlerini çağırmak istememenizdir.

Python'da super kullanımı hakkında oldukça önemli bir literatür var ve ben de konuya google'ı öneririm ve sonuçları okurum.

4

ASDF1 (üst sınıflarınızdan biri) super() öğesine yapılan ilk argüman olarak geçiyorsunuz. Bunu yapma. Bunun yerine, ASDF'yi super() için ilk argüman olarak geçirmelisiniz.

Python 2.7 documentation for super()

Python 2.7 docs alıntı, tipik bir üst sınıf çağrı şuna benzer: İlk argüman süper burada geçerli sınıftır C olduğu için

class C(B): 
    def method(self, arg): 
     super(C, self).method(arg) 

Bildirim söyledi. B'yi (üst sınıf) süper() öğesine geçirmeyin.

Yöntem Çözünürlük Sırasını (MRO) belirlerken, süper ilk argümanı olarak geçilen sınıfı atlar ve bu sınıfa bakmaya başlar 'ebeveynler ve kardeşler. Yani, ASDF1'i super() öğesine ilk argüman olarak geçtiğinizde, ASDF1 üzerinden atlandı ve ASDF2 ile aramaya başladı. Bu yüzden ASDF2'nin __init__ çağrıldı.


Python 3'te, şimdiki sınıfı geçmek zorunda değilsiniz.

class C(B): 
    def method(self, arg): 
     super().method(arg) # This does the same thing as: 
           # super(C, self).method(arg) 
           # (Python 3 only) 
İlgili konular