मैं आधार (सुपर) वर्ग को कैसे शुरू करूं?


125

पायथन में, विचार करें कि मेरे पास निम्नलिखित कोड हैं:

>>> class SuperClass(object):
    def __init__(self, x):
        self.x = x

>>> class SubClass(SuperClass):
    def __init__(self, y):
        self.y = y
        # how do I initialize the SuperClass __init__ here?

मैं SuperClass __init__उपवर्ग में कैसे आरंभ करूं ? मैं पायथन ट्यूटोरियल का अनुसरण कर रहा हूं और यह कवर नहीं करता है। जब मैंने Google पर खोज की, तो मुझे करने का एक से अधिक तरीका मिला। इसे संभालने का मानक तरीका क्या है?

जवाबों:


146

पायथन (संस्करण 3 तक) "पुरानी शैली" और नई शैली की कक्षाओं का समर्थन करता है। नई-शैली की कक्षाओं से व्युत्पन्न हैं objectऔर वे हैं जो आप उपयोग कर रहे हैं, और super()उदाहरण के माध्यम से अपने आधार वर्ग का आह्वान करते हैं

class X(object):
  def __init__(self, x):
    pass

  def doit(self, bar):
    pass

class Y(X):
  def __init__(self):
    super(Y, self).__init__(123)

  def doit(self, foo):
    return super(Y, self).doit(foo)

क्योंकि अजगर पुरानी और नई शैली की कक्षाओं के बारे में जानता है, इसलिए आधार पद्धति को लागू करने के विभिन्न तरीके हैं, यही वजह है कि आपने ऐसा करने के कई तरीके ढूंढे हैं।

संपूर्णता के लिए, पुरानी शैली की कक्षाएं बेस क्लास का उपयोग करके स्पष्ट रूप से आधार विधियों को कॉल करती हैं, अर्थात

def doit(self, foo):
  return X.doit(self, foo)

लेकिन जब से आप पुरानी शैली का उपयोग नहीं कर रहे हैं, मैं इस बारे में बहुत ज्यादा परवाह नहीं करेगा।

पायथन 3 केवल नई-शैली की कक्षाओं के बारे में जानता है (कोई फर्क नहीं पड़ता कि आप इससे प्राप्त करते हैं objectया नहीं)।


37

दोनों

SuperClass.__init__(self, x)

या

super(SubClass,self).__init__( x )

काम करेगा (मैं दूसरा पसंद करता हूं, क्योंकि यह DRY सिद्धांत का अधिक पालन करता है)।

यहां देखें: http://docs.python.org/reference/datamodel.html#basic-customization


8
गलत। सुपर केवल नई शैली की कक्षाओं के साथ काम करता है, और नई शैली की कक्षाओं का उपयोग करते समय आधार को कॉल करने का एकमात्र उचित तरीका है। इसके अलावा, आपको पुरानी शैली के निर्माण का उपयोग करके स्पष्ट रूप से 'स्व' पास करना होगा।
इवो ​​वैन डेर विज्क सेप

1
@ इवो - ओपी ने उदाहरण में एक नई शैली की कक्षा दी, और नई शैली और पुरानी शैली के बीच अंतर के बारे में बात करने में बहुत कम बिंदु है क्योंकि किसी को भी पुरानी शैली का उपयोग नहीं करना चाहिए। मैंने (पायथन डॉक्स को) जो लिंक दिया, वह बताता है कि सुपर क्लास को कॉल करने का एक से अधिक "उचित" तरीका है __init__
adamk


21

मैं आधार (सुपर) वर्ग को कैसे शुरू करूं?

class SuperClass(object):
    def __init__(self, x):
        self.x = x

class SubClass(SuperClass):
    def __init__(self, y):
        self.y = y

superविधि रिज़ॉल्यूशन ऑर्डर में आपको अगली विधि (एक बाध्य विधि के रूप में) प्राप्त करने के लिए एक ऑब्जेक्ट का उपयोग करें । पायथन 2 में, आपको selfबाउंड __init__मेथड देखने के लिए क्लास का नाम और सुपर पास करना होगा :

 class SubClass(SuperClass):
      def __init__(self, y):
          super(SubClass, self).__init__('x')
          self.y = y

पायथन 3 में, थोड़ा जादू है जो तर्कों को superअनावश्यक बनाता है - और एक पक्ष लाभ के रूप में यह थोड़ा तेज़ काम करता है:

 class SubClass(SuperClass):
      def __init__(self, y):
          super().__init__('x')
          self.y = y

नीचे दिए गए माता-पिता को इस तरह से हार्डकोर करना आपको सहकारिता के कई उत्तराधिकार का उपयोग करने से रोकता है:

 class SubClass(SuperClass):
      def __init__(self, y):
          SuperClass.__init__(self, 'x') # don't do this
          self.y = y

ध्यान दें कि __init__केवल वापस आ सकता हैNone - इसका उद्देश्य ऑब्जेक्ट को जगह में संशोधित करना है।

कुछ कुछ __new__

उदाहरणों को शुरू करने का एक और तरीका है - और यह पायथन में अपरिवर्तनीय प्रकारों के उपवर्गों का एकमात्र तरीका है। यदि आप उपवर्ग strया करना चाहते हैं तो यह आवश्यक हैtuple किसी अन्य अपरिवर्तनीय वस्तु को चाहते हैं।

आप सोच सकते हैं कि यह एक वर्गमंथन है क्योंकि इसमें एक अंतर्निहित वर्ग तर्क मिलता है। लेकिन यह वास्तव में एक स्टेथमिथोड है । तो अगर आप कॉल करने की आवश्यकता __new__के साथ clsस्पष्ट रूप से।

हम आमतौर पर उदाहरण से लौटते हैं __new__, इसलिए यदि आप करते हैं, तो आपको अपने आधार के __new__माध्यम से superअपने आधार वर्ग में भी कॉल करना होगा । इसलिए यदि आप दोनों विधियों का उपयोग करते हैं:

class SuperClass(object):
    def __new__(cls, x):
        return super(SuperClass, cls).__new__(cls)
    def __init__(self, x):
        self.x = x

class SubClass(object):
    def __new__(cls, y):
        return super(SubClass, cls).__new__(cls)

    def __init__(self, y):
        self.y = y
        super(SubClass, self).__init__('x')

पायथन 3 __new__स्थैतिक विधि से होने वाली सुपर कॉल्स की अजीबता को थोड़ा कम करता है , लेकिन फिर भी आपको clsगैर-बाध्य __new__विधि से गुजरना होगा :

class SuperClass(object):
    def __new__(cls, x):
        return super().__new__(cls)
    def __init__(self, x):
        self.x = x

class SubClass(object):
    def __new__(cls, y):
        return super().__new__(cls)
    def __init__(self, y):
        self.y = y
        super().__init__('x')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.