पायथन में वंशानुक्रम और प्रवेश विधि


98

मैं अजगर का भिखारी हूं। मैं विरासत और समझ नहीं सकता __init__()

class Num:
    def __init__(self,num):
        self.n1 = num

class Num2(Num):
    def show(self):
        print self.n1

mynumber = Num2(8)
mynumber.show()

परिणाम: 8

यह ठीक है। लेकिन मैं के Num2साथ बदलें

class Num2(Num):
    def __init__(self,num):
        self.n2 = num*2
    def show(self):
        print self.n1,self.n2

परिणाम: Error. Num2 has no attribute "n1".

इस मामले में, कैसे Num2पहुंच सकते हैं n1?

जवाबों:


151

पहली स्थिति में, Num2वर्ग प्रदान कर रहा है Numऔर आप के बाद से फिर से परिभाषित करने नहीं कर रहे हैं विशेष विधि नामित __init__()में Num2, यह से विरासत में मिला हो जाता है Num

जब एक कक्षा एक __init__() विधि को परिभाषित करती है , तो क्लास इंस्टेंटेशन स्वचालित रूप __init__()से नव-निर्मित क्लास इंस्टेंस के लिए आमंत्रित करता है ।

दूसरी स्थिति में, जब से तुम को पुनर्परिभाषित कर रहे हैं __init__()में Num2आप स्पष्ट रूप से सुपर वर्ग (में एक कॉल करने की आवश्यकता Num) यदि आप अपने व्यवहार का विस्तार करना चाहते हैं।

class Num2(Num):
    def __init__(self,num):
        Num.__init__(self,num)
        self.n2 = num*2

27
आपका उद्धरण यह समझाने के लिए पर्याप्त नहीं है कि, जब किसी __init__पद्धति को एक व्युत्पन्न वर्ग में परिभाषित नहीं किया जाता है, तो यह विरासत में मिलती है। ऐसा इसलिए है क्योंकि "यदि एक अनुरोधित विशेषता वर्ग में नहीं पाई जाती है, तो खोज बेस क्लास में देखने के लिए आगे बढ़ती है।" (डॉक)
२२

6
मुझे खेद है ... कि मूल रूप से वंशानुक्रम कैसे काम करता है ... यदि आपको एक वर्ग विरासत में मिला है, तो आपको पूरा पैकेज मिलता है, इसलिए, उपवर्ग में सब कुछ सुपरक्लास में मौजूद है। लेकिन, यदि आप एक विधि को फिर से परिभाषित करते हैं, तो यह अधिक हो जाता है ... यही आपके कोड में है।
कोया

5
@ mario-duarte किसी भी कारण से यह बेहतर क्यों होगा super(Num2, self).__init__(num)?
18'18

1
मैं सिर्फ इस समाधान में प्रस्तावित समाधान से स्विच करने का उपयोग कर रहा superहूं, और मेरा कार्यक्रम अब कुछ सेकंड तेजी से लोड होता है। पता नहीं क्यों।
गुइमूटे

superएकाधिक वंशानुक्रम का उपयोग करते समय सहायक माना जाता है। एकल वंशानुक्रम के लिए इसके लाभ स्पष्ट नहीं हैं।
जोहान ब्रज



4

इस तरह Num2 वर्ग में एक साधारण परिवर्तन:

super().__init__(num) 

यह python3 में काम करता है।

class Num:
        def __init__(self,num):
                self.n1 = num

class Num2(Num):
        def __init__(self,num):
                super().__init__(num)
                self.n2 = num*2
        def show(self):
                print (self.n1,self.n2)

mynumber = Num2(8)
mynumber.show()

2
यही कारण है कि मुझे स्टैकओवरफ्लो से प्यार है। हालांकि यह सवाल का जवाब नहीं है यह उपयोगी है। कभी-कभी जो उत्तर लोग पोस्ट करते हैं, वे उस प्रश्न के उत्तर होते हैं जो लोगों को पूछना चाहिए था। धन्यवाद!
ग्लेन थॉम्पसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.