पाइथन सुपर () टाइप इयरर को बढ़ाता है


109

पायथन 2.5 में, निम्न कोड एक उठाता है TypeError:

>>> class X:
      def a(self):
        print "a"

>>> class Y(X):
      def a(self):
        super(Y,self).a()
        print "b"

>>> c = Y()
>>> c.a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in a
TypeError: super() argument 1 must be type, not classobj

यदि मैं इसके class Xसाथ प्रतिस्थापित करता हूं class X(object), तो यह काम करेगा। इसके लिए क्या स्पष्टीकरण है?


3
आपकी "हालाँकि मैं दसवीं कक्षा को कक्षा X (ऑब्जेक्ट) से बदल देता हूँ" मेरी समस्या को ठीक कर दिया है! thanx
अलीबज

जवाबों:


132

कारण यह है कि super()केवल नई शैली की कक्षाओं पर काम करता है , जो 2.x श्रृंखला में इसका मतलब है object:

>>> class X(object):
        def a(self):
            print 'a'

>>> class Y(X):
        def a(self):
            super(Y, self).a()
            print 'b'

>>> c = Y()
>>> c.a()
a
b

4
किस अजगर संस्करण से यह डिफ़ॉल्ट व्यवहार बन गया?
जियो

6
2.2 था जब नई शैली की कक्षाएं शुरू की गई थीं, 3.0 वह जगह है जहां वे डिफ़ॉल्ट हो गए।
कोड़ी ब्रोचेस

7
@ सूतमी यदि आप सुपरक्लास में जाना चाहते हैं, तो "Xa (स्वयं)" करें
जेम्स ब्रैडी

मुझे लगता है आपने मुझे गलत समझ लिया । त्रिपिटक। मुझे याद है कि मैं 3.0 से कम एक अजगर संस्करण का उपयोग कर रहा था, और मैंने विशेष रूप से यह नहीं कहा कि मेरी कक्षा ऑब्जेक्ट से विरासत में मिली है, और सुपर काम करने के लिए कॉल। शायद यह 2.6 से डिफ़ॉल्ट व्यवहार है? सिर्फ :) :)
जियो

अलबास्टर, वास्तव में इसके लिए कोई ज़रूरत नहीं है। नई शैली की कक्षाओं में केवल सुपर ही नहीं बल्कि भारी संख्या में लाभ हैं। पुरानी शैली के तरीकों को बढ़ावा नहीं दिया जाना चाहिए।
कोड़ी ब्रोशर

14

इसके अलावा, सुपर का उपयोग न करें () जब तक आपको नहीं करना है। यह नई शैली की कक्षाओं के साथ करने के लिए सामान्य उद्देश्य "सही बात" नहीं है जो आपको संदेह हो सकता है।

ऐसे समय होते हैं जब आप कई उत्तराधिकार की उम्मीद कर रहे होते हैं और आप संभवतः इसे प्राप्त कर सकते हैं, लेकिन जब तक आप एमआरओ के बालों के विवरण को नहीं जानते हैं, तब तक इसे अकेले छोड़ दें और यहां रहें:

 X.a(self)

2
क्या यह सही है क्योंकि मेरे 6 महीने के पायथन / Django में मैं "सामान्य सही काम करने के लिए" के रूप में सुपर का उपयोग कर रहा हूं?
फिल्गो २०

1
वैसे यह आपको अपने आप में एकल वंशानुक्रम के लिए चोट नहीं पहुँचाता (सिवाय इसके कि यह थोड़ा धीमा है), लेकिन यह आपको अपने आप कुछ भी नहीं मिलता है। आपको किसी भी तरीके को डिज़ाइन __init__करना होगा, जो एक साफ और समझदार तरीके से तर्कों के माध्यम से पारित करने के लिए (सबसे विशेष रूप से ) गुणा करने की आवश्यकता है , अन्यथा आपको टाइपरियर्स या बदतर डिबगिंग समस्याएं मिलेंगी जब कोई व्यक्ति अपनी कक्षा का उपयोग करके गुणा-भाग करने की कोशिश करता है। जब तक आपने वास्तव में एमआई को इस तरह से समर्थन देने के लिए डिज़ाइन किया है (जो कि काफी मुश्किल है), तो निहितार्थ से बचने के लिए संभवतः बेहतर superहै कि विधि एमआई-सुरक्षित हो।
बॉबीस

3

मामले में उपरोक्त में से किसी भी उत्तर ने स्पष्ट रूप से उल्लेख नहीं किया है। आपके मूल वर्ग को "ऑब्जेक्ट" से विरासत में प्राप्त करने की आवश्यकता है, जो अनिवार्य रूप से इसे एक नई शैली वर्ग में बदल देगा।

# python 3.x:
class ClassName(object): # This is a new style class
    pass

class ClassName: # This is also a new style class ( implicit inheritance from object )
    pass

# Python 2.x:
class ClassName(object): # This is a new style class
    pass

class ClassName:         # This is a old style class
    pass

क्षमा करें, लेकिन Python 3.x में आपका दूसरा उदाहरण (अंतर्निहित विरासत) वास्तव में उल्लेखित मुद्दे के संदर्भ में काम नहीं करता है।
sophros

1

मैंने विभिन्न Xa () विधियों की कोशिश की; हालाँकि, उन्हें एक () करने के लिए X के उदाहरण की आवश्यकता होती है, इसलिए मैंने X () (a) (सेल्फ) किया, जो पिछले उत्तरों की तुलना में अधिक पूर्ण प्रतीत होता है, कम से कम उन अनुप्रयोगों के लिए जो मैंने सामना किया है। यह समस्या से निपटने का एक अच्छा तरीका नहीं है क्योंकि अनावश्यक निर्माण और विनाश है, लेकिन यह ठीक काम करता है।

मेरा विशिष्ट अनुप्रयोग पायथन का cmd.Cmd मॉड्यूल था, जो स्पष्ट रूप से किसी कारण से एक न्यूसेटल ऑब्जेक्ट नहीं है।

अंतिम परिणाम:

X().a(self)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.