সুপার () ত্রুটির সাথে ব্যর্থ হয়: টাইপররার "আর্গুমেন্ট 1 টি টাইপ করতে হবে, ক্লাসোবজ নয়" যখন পিতামাতারা বস্তু থেকে উত্তরাধিকার সূত্রে না পান


196

আমি কিছু ত্রুটি পেয়েছি যা আমি বুঝতে পারি না। আমার স্যাম্পল কোডটিতে কী ভুল আছে তা সম্পর্কে কোনও সূত্র?

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

এফওয়াইআই, অজগর থেকে নিজেই এখানে সহায়তা (সুপার) দিচ্ছেন:

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)
 |


3
মেথ ?? এটি কি প্রোগ্রামিং শব্দ, বা ... আপনি জানেন? পরিষ্কার করে বলো.
সিপিপ্লসপ্লসপ্লাস

3
@ ক্লিপস্লপসপ্লস: সম্ভবত পদ্ধতিটির জন্য দাঁড়িয়েছে ;-)
শ্যাডফ্লেমে

উত্তর:


333

আপনার সমস্যাটি হ'ল ক্লাস বিটিকে "নতুন ধাঁচের" শ্রেণি হিসাবে ঘোষণা করা হয়নি। এটি এর মতো পরিবর্তন করুন:

class B(object):

এবং এটি কাজ করবে।

super()এবং সমস্ত সাবক্লাস / সুপারক্লাস স্টাফ কেবল নতুন স্টাইলের ক্লাসগুলির সাথে কাজ করে। আমি আপনাকে সুপারিশ করি যে (object)এটি সর্বদা টাইপ করার অভ্যাসে যে কোনও শ্রেণির সংজ্ঞা অনুসারে এটি একটি নতুন-শৈলীর শ্রেণি make

পুরানো স্টাইলের ক্লাসগুলি ("ক্লাসিক" ক্লাস হিসাবেও পরিচিত) সর্বদা টাইপ থাকে 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 এ আপনার সমস্যা হবে না।


আকর্ষণীয়, আমি এই সঠিক সমস্যাটি বটল.পি ( বোতলপি.অর্গ ) চলমান অবস্থায় পেয়েছি যা একই ধরণের ত্রুটি ছুড়ে ফেলে ( টাইপরর : অবশ্যই টাইপ হওয়া উচিত, ক্লায়োবজ নয়) পাই 27 এ চলছে তবে পাই 33 নয়।
বুটলোড

পাইথন ৩.x এ আর "পুরানো ধাঁচের" ক্লাস নেই। "পুরানো-শৈলী" ঘোষণা ব্যবহার করে কোডটি এখনও একটি "নতুন-স্টাইল" শ্রেণি ঘোষণা করে, তাই পাইথন ৩.x এ এই ত্রুটিটি ঘটতে পারে না।
স্টিভেহা

1
ক্লাস বি আপনার সম্পাদনার জন্য উপলভ্য না হলে ব্যবহারের চেষ্টা না করার জন্য আপনাকে অবশ্যই ক্লাস এ এডিট করতে হবে super(); ক্লাস এটিকে অবশ্যই "পুরাতন-শৈলী" শ্রেণীর সাথে কাজ করতে হবে এবং সম্ভবত এটি করার সর্বোত্তম উপায় হবে ক্লাস এটিকে নিজেই একটি "পুরাতন-শৈলী" শ্রেণিতে পরিণত করা। অবশ্যই আমি পাইথন ৩.x এ চালানোর জন্য আপনার পুরো প্রোগ্রামটিকে আপগ্রেড করার পরামর্শ দিচ্ছি, যাতে আপনি যা কিছু করেন না কেন সমস্ত ক্লাসই নতুন ধাঁচের হয়ে উঠবে; যদি সেই বিকল্পটি উপলব্ধ থাকে তবে এটি সর্বোত্তম বিকল্প।
স্টিভাহ

আমার একই সমস্যা আছে তবে আমার বেস ক্লাসটি এর মতো ঘোষিত হয়েছে class B(object):@mock.patch('module.B', autospec=B)আমার পরীক্ষার মামলার ঠিক আগে ব্যবহার করার কারণে আমি এই ত্রুটিটি পাচ্ছি। এটি ঠিক করার জন্য কোন চিন্তা?
মাইকেই

154

এছাড়াও, আপনি ক্লাস বি পরিবর্তন করতে না পারলে আপনি একাধিক উত্তরাধিকার ব্যবহার করে ত্রুটিটি ঠিক করতে পারেন।

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)

16
আমি কোনও মন্তব্য রাখতে সহায়তা করতে পারিনি, এটির 'মানক' উত্তর হিসাবে গ্রহণ করা উচিত।
workplaylifecycle

9
ভবিষ্যতের গুগলরা পাইথন ২.6 এ আটকে রয়েছে: এটি সম্ভবত আপনি উত্তর চান এটি উত্তর! আপনি যখন বেস ক্লাসটি পরিবর্তন করতে পারবেন না (যেমন আপনি একটি স্ট্যান্ডার্ড লাইব্রেরি ক্লাসটি সাবক্লাস করছেন) তখন আপনার নিজের শ্রেণিতে এই পরিবর্তনটি সুপার () ঠিক করে দেয়।
coredumperror

এটি আমার পক্ষে ভাল কাজ করেছে, আপনি কি কেউ ব্যাখ্যা করতে পারেন যে এটি কীভাবে কাজ করে?
সুব্রো

@ সুব্রো, এটি আপনার ক্লাসকে একটি "নতুন-স্টাইল" শ্রেণি করে তোলে (যেখানে শ্রেণি অবজেক্ট টাইপ করা হয় type) এখনও একটি "পুরানো-শৈলী" শ্রেণি ( যেখানে শ্রেণীর অবজেক্ট টাইপ করা হয় ) সাবক্লাসিংয়ের সময় classobjsuper()নতুন-স্টাইলের ক্লাসগুলির সাথে কাজ করে তবে পুরাতন স্টাইলের ক্লাসগুলির সাথে নয়।
মারসফট

নিখুঁত উত্তর!
টম

18

পাইথন সংস্করণটি যদি 3. এক্স হয় তবে তা ঠিক আছে।

আমার মনে হয় আপনার অজগর সংস্করণটি 2.X, এই কোডটি যুক্ত করার সময় সুপার কাজ করবে

__metaclass__ = type

সুতরাং কোড হয়

__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)

4

অজগর ২.7 ব্যবহার করার সময় আমি পোস্ট করা সমস্যার মুখোমুখি হয়েছি। এটি অজগর 3.4 দিয়ে খুব সূক্ষ্মভাবে কাজ করছে

এটি অজগর ২. in এ কাজ করতে আমি __metaclass__ = typeআমার প্রোগ্রামের শীর্ষে বৈশিষ্ট্যটি যুক্ত করেছি এবং এটি কাজ করেছে।

__metaclass__ : এটি পুরানো স্টাইলের ক্লাস এবং নতুন স্টাইলের ক্লাস থেকে স্থানান্তরকে সহজ করে দেয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.