2011-11-04 22 views
8

संभव डुप्लिकेट:
Can Super deal with multiple inheritance?सुपर के साथ कई पैरेंट कक्षाओं के लिए init कॉलिंग?

अजगर विरासत? मेरे पास एक वर्ग संरचना है (नीचे), और चाहते हैं कि बच्चे वर्ग दोनों माता-पिता के __init__ पर कॉल करें। क्या यह 'सुपर' तरीके से करना संभव है या क्या यह सिर्फ एक भयानक विचार है?

class Parent1(object): 
    def __init__(self): 
     self.var1 = 1 

class Parent2(object): 
    def _init__(self): 
     self.var2 = 2 

class Child(Parent1, Parent2): 
    def __init__(self): 
     ## call __init__ of Parent1 
     ## call __init__ of Parent2 
     ## super(Child, self).__init__() 

उत्तर

17

के माध्यम से प्रार्थना किए super सभी माता पिता को फोन नहीं है, यह एमआरओ श्रृंखला में अगले समारोह कहता है। इस ठीक से काम करने के लिए, आप __init__ रों के सभी में super उपयोग करने की आवश्यकता:

class Parent1(object): 
    def __init__(self): 
     super(Parent1, self).__init__() 
     self.var1 = 1 

class Parent2(object): 
    def __init__(self): 
     super(Parent2, self).__init__() 
     self.var2 = 2 

class Child(Parent1, Parent2): 
    def __init__(self): 
     super(Child, self).__init__() 

अजगर 3 में, आप super() बजाय super(type, instance) उपयोग कर सकते हैं।

+0

मैंने कई अन्य प्रश्न और उत्तर पढ़े हैं, आपका एकमात्र ऐसा व्यक्ति है जो 'सुपर()' को "एमआरओ श्रृंखला में अगला कार्य" कहता है। वास्तव में एक सरल अभी तक बहुत महत्वपूर्ण बयान। – MikeyE

26

super() के विचार आप दोनों सुपर-क्लास '__init__() तरीकों अलग से बुला परेशान करने के लिए नहीं है कि है - एक स्पष्टीकरण के लिए Raymond Hettinger's "Python’s super() considered super!" देखते हैं - super() आप इसे सही ढंग से उपयोग करते समय प्रदान, यह ध्यान रखना होगा।

उस ने कहा, मुझे फायदे से अधिक कन्स्ट्रक्टर कॉल के लिए super() के नुकसान अक्सर मिलते हैं। उदाहरण के लिए, आपके सभी रचनाकारों को अतिरिक्त **kwargs तर्क प्रदान करने की आवश्यकता है, सभी वर्गों को सहयोग करना चाहिए, गैर-सहयोगी बाहरी वर्गों को एक रैपर की आवश्यकता है, आपको यह ध्यान रखना होगा कि प्रत्येक कन्स्ट्रक्टर पैरामीटर नाम पर सभी आपकी कक्षाएं आदि

तो अधिक बार नहीं की तुलना में, मुझे लगता है कि यह आसान है स्पष्ट रूप से आधार वर्ग तरीकों आप निर्माता के लिए कॉल करना चाहते हैं कॉल नाम के लिए:

class Child(Parent1, Parent2): 
    def __init__(self): 
     Parent1.__init__(self) 
     Parent2.__init__(self) 

मैं कार्यों एक गारंटीकृत प्रोटोटाइप होती हैं, के super() प्रयोग करते हैं, __getattr__() की तरह , हालांकि। इन मामलों में नुकसान नहीं हैं।

7

तुम बस उन्हें Parent.__init__(self) के साथ सीधे कह सकते हैं:

class Parent1(object): 
    def __init__(self): 
        self.var1 = 1 

class Parent2(object): 
    def _init__(self): 
        self.var2 = 2 

class Child(Parent1, Parent2): 
    def __init__(self): 
     Parent1.__init__(self) 
     Parent2.__init__(self)