2009-11-11 15 views
112

मुझे कुछ त्रुटि मिलती है जिसे मैं समझ नहीं सकता। कोई भी संकेत मेरे नमूना कोड के साथ क्या गलत है?सुपर() त्रुटि के साथ विफल रहता है: TypeError "तर्क 1 टाइप होना चाहिए, classobj नहीं"

class B: 
    def meth(self, arg): 
     print arg 

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

print C().meth(1) 

मुझे 'सुपर' अंतर्निहित विधि की सहायता से नमूना परीक्षण कोड मिला। वर्ग 'सी'

यहाँ त्रुटि है:

Traceback (most recent call last): 
    File "./test.py", line 10, in ? 
    print C().meth(1) 
    File "./test.py", line 8, in meth 
    super(C, self).meth(arg) 
TypeError: super() argument 1 must be type, not classobj 

FYI करें, यहाँ मदद (सुपर) अजगर से ही है:

Help on class super in module __builtin__: 

class super(object) 
| super(type) -> unbound super object 
| super(type, obj) -> bound super object; requires isinstance(obj, type) 
| super(type, type2) -> bound super object; requires issubclass(type2, type) 
| Typical use to call a cooperative superclass method: 
| class C(B): 
|  def meth(self, arg): 
|   super(C, self).meth(arg) 
| 
+0

[पाइथन सुपर() के संभावित डुप्लिकेट TypeError उठाता है! क्यों?] (Http://stackoverflow.com/questions/489269/python-super-raises-typeerror- क्यों) – user

+1

मेथ ?? क्या यह एक प्रोग्रामिंग शब्द है, या ... पता है? कृपया स्पष्ट करें। – Cplusplusplus

+2

@Cplusplusplus: शायद विधि के लिए खड़ा है ;-) – ShadowFlame

उत्तर

197

आपका समस्या यह है कि वर्ग बी है एक "नई शैली" वर्ग के रूप में घोषित नहीं किया गया। इसे इस प्रकार बदलें:

class B(object): 

और यह काम करेगा।

super() और सभी सबक्लास/सुपरक्लास सामान केवल नए शैली के वर्गों के साथ काम करता है। मैं आपको यह सुनिश्चित करने के लिए कि यह एक नई शैली की कक्षा है, किसी भी कक्षा परिभाषा पर हमेशा (object) टाइप करने की आदत प्राप्त करने की सलाह देते हैं।

पुरानी शैली के वर्ग (जिसे "क्लासिक" कक्षाओं के नाम से भी जाना जाता है) हमेशा classobj टाइप होते हैं; नई शैली के वर्ग type प्रकार के हैं। यही कारण है कि आप त्रुटि संदेश देखा है:

TypeError: super() argument 1 must be type, not classobj

इस प्रयास करें खुद के लिए देखने के लिए:

class OldStyle: 
    pass 

class NewStyle(object): 
    pass 

print type(OldStyle) # prints: <type 'classobj'> 

print type(NewStyle) # prints <type 'type'> 

ध्यान दें कि अजगर 3.x में सभी वर्गों नई शैली है। आप अभी भी पुरानी शैली के वर्गों से वाक्यविन्यास का उपयोग कर सकते हैं लेकिन आपको एक नई शैली की कक्षा मिलती है। तो, पायथन 3.x में आपको यह समस्या नहीं होगी।

+0

दिलचस्प, मुझे यह सटीक समस्या मिली है जो बोतल.py (http://bottlepy.org) चला रही है जो एक समान त्रुटि फेंकता है (TypeError: टाइप होना चाहिए, क्लासोबोज नहीं होना चाहिए) Py27 पर चल रहा है लेकिन Py33 नहीं। – bootload

+0

पायथन 3.x में, अब "पुरानी शैली" कक्षाएं नहीं हैं। "पुरानी शैली" घोषणा का उपयोग करके कोड अभी भी एक "नई शैली" वर्ग घोषित करता है, इसलिए यह त्रुटि पायथन 3.x में नहीं हो सकती है। – steveha

+0

क्या होगा यदि कक्षा बी आपके लिए संपादित करने के लिए उपलब्ध नहीं है? –

92

इसके अलावा, यदि आप कक्षा बी नहीं बदल सकते हैं, तो आप एकाधिक विरासत का उपयोग करके त्रुटि को ठीक कर सकते हैं।

class B: 
    def meth(self, arg): 
     print arg 

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

print C().meth(1) 
+2

दूसरी ऑब्जेक्ट क्लास के रूप में 'ऑब्जेक्ट' एक अच्छी चाल है। –

+7

मैं कोई टिप्पणी छोड़ने में मदद नहीं कर सका, इसे 'मानक' उत्तर के रूप में स्वीकार किया जाना चाहिए। – hylepo

+4

भविष्य के googlers के लिए Python 2.6 पर फंस गया: यह वह जवाब है जिसे आप शायद चाहते हैं! जब आप बेस क्लास को बदल नहीं सकते हैं (उदा। आप मानक लाइब्रेरी क्लास को उपclassing कर रहे हैं), यह आपकी खुद की कक्षा में परिवर्तन सुपर() को हल करता है। – CoreDumpError

10

यदि पायथन संस्करण 3.X है, तो यह ठीक है।

मुझे लगता है कि अपने अजगर संस्करण 2.x है, सुपर जब यह कोड जोड़ने

__metaclass__ = type 
class B: 
    def meth(self, arg): 
     print arg 
class C(B): 
    def meth(self, arg): 
     super(C, self).meth(arg) 
print C().meth(1) 
2

मैं भी तैनात समस्या से सामना करना पड़ा था

__metaclass__ = type 

तो कोड है काम करेगा जब मैं प्रयुक्त पायथन 2.7। यह पाइथन 3.4

इसे पायथन 2.7 में काम करने के लिए बहुत अच्छा काम कर रहा है। मैंने अपने कार्यक्रम के शीर्ष पर __metaclass__ = type विशेषता जोड़ा है और यह काम करता है।

__metaclass__: यह पुरानी शैली के वर्गों और नई शैली के वर्गों से संक्रमण को आसान बनाता है।

संबंधित मुद्दे

 संबंधित मुद्दे