การสืบทอด Python: TypeError: object .__ init __ () ไม่มีพารามิเตอร์


92

ฉันได้รับข้อผิดพลาดนี้:

TypeError: object.__init__() takes no parameters 

เมื่อรันโค้ดของฉันฉันไม่เห็นว่าฉันทำอะไรผิดที่นี่:

class IRCReplyModule(object):

    activated=True
    moduleHandlerResultList=None
    moduleHandlerCommandlist=None
    modulename=""

    def __init__(self,modulename):
        self.modulename = modulename


class SimpleHelloWorld(IRCReplyModule):

     def __init__(self):
            super(IRCReplyModule,self).__init__('hello world')

คำตอบ:


118

คุณเรียกชื่อคลาสผิดในการโทร super () ของคุณ:

class SimpleHelloWorld(IRCReplyModule):

     def __init__(self):
            #super(IRCReplyModule,self).__init__('hello world')
            super(SimpleHelloWorld,self).__init__('hello world')

โดยพื้นฐานแล้วสิ่งที่คุณกำลังแก้ไขคือ__init__คลาสฐานอ็อบเจ็กต์ซึ่งไม่ต้องใช้พารามิเตอร์

ฉันรู้ว่ามันซ้ำซ้อนเล็กน้อยที่จะต้องระบุคลาสที่คุณมีอยู่แล้วซึ่งเป็นเหตุผลว่าทำไมใน python3 คุณสามารถทำได้: super().__init__()


4
@LucasKauffman: อันที่จริงฉันไม่คิดว่ามันโง่มากสำหรับคุณ อาจเป็นแนวคิดที่สับสนได้อย่างง่ายดาย ผมไม่โทษคุณ
jdi

4
เสี่ยงต่อการละเมิด Pythonians หลายคนนั่นคือ imho - เป็นการออกแบบภาษาที่แย่มาก ขอบคุณสำหรับความช่วยเหลือของคุณ @jdi!
Johannes Fahrenkrug

4
@JohannesFahrenkrug - ฉันไม่คิดว่าคุณจะทำให้ใครขุ่นเคืองเพราะนั่นถูกระบุว่าเป็นการออกแบบที่ไม่ดีและแก้ไขใน python3: docs.python.org/3/library/functions.html#super
jdi

3

สิ่งนี้กัดฉันสองครั้งเมื่อเร็ว ๆ นี้ (ฉันรู้ว่าฉันควรได้เรียนรู้จากความผิดพลาดของฉันในครั้งแรก) และคำตอบที่ได้รับการยอมรับก็ไม่ได้ช่วยฉันสักครั้งดังนั้นในขณะที่ฉันคิดอยู่ในใจฉันคิดว่าฉันจะส่งคำตอบของตัวเองในกรณี มีใครกำลังเจอปัญหานี้อยู่ (หรือฉันต้องการสิ่งนี้อีกในอนาคต)

ในกรณีของฉันปัญหาคือฉันส่ง kwarg ไปยังการเริ่มต้นของคลาสย่อย แต่ในซูเปอร์คลาสนั้นคีย์เวิร์ดนั้นจะถูกส่งผ่านไปยังการเรียก super ()

ฉันมักจะคิดว่าสิ่งเหล่านี้ดีที่สุดโดยมีตัวอย่าง:

class Foo(object):
  def __init__(self, required_param_1, *args, **kwargs):
    super(Foo, self).__init__(*args, **kwargs)
    self.required_param = required_param_1
    self.some_named_optional_param = kwargs.pop('named_optional_param', None)

  def some_other_method(self):
    raise NotImplementedException

class Bar(Foo):
  def some_other_method(self):
    print('Do some magic')


Bar(42) # no error
Bar(42, named_optional_param={'xyz': 123}) # raises TypeError: object.__init__() takes no parameters

ดังนั้นในการแก้ไขปัญหานี้ฉันต้องเปลี่ยนลำดับที่ฉันทำสิ่งต่างๆในเมธอด Foo .__ init__; เช่น:

class Foo(object):
  def __init__(self, required_param_1, *args, **kwargs):
    self.some_named_optional_param = kwargs.pop('named_optional_param', None)
    # call super only AFTER poping the kwargs
    super(Foo, self).__init__(*args, **kwargs)
    self.required_param = required_param_1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.