Kế thừa Python: TypeError: object .__ init __ () không có tham số


90

Tôi gặp lỗi này:

TypeError: object.__init__() takes no parameters 

khi chạy mã của mình, tôi thực sự không thấy mình đang làm gì sai ở đây:

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

Câu trả lời:


115

Bạn đang gọi sai tên lớp trong lệnh gọi super () của mình:

class SimpleHelloWorld(IRCReplyModule):

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

Về cơ bản những gì bạn đang giải quyết là __init__của lớp cơ sở đối tượng mà không có tham số.

Tôi biết là hơi thừa khi phải chỉ định lớp mà bạn đã ở trong đó, đó là lý do tại sao trong python3 bạn chỉ có thể làm: super().__init__()


4
@LucasKauffman: Thực ra tôi không nghĩ chuyện đó thật ngớ ngẩn của bạn. Nó có thể dễ dàng là một khái niệm khó hiểu. Tôi không trách bạn.
jdi

4
Có nguy cơ xúc phạm nhiều người Pythonians: Đó - imho - là thiết kế ngôn ngữ khủng khiếp. Cảm ơn bạn đã giúp đỡ @jdi!
Johannes Fahrenkrug

4
@JohannesFahrenkrug - Tôi không nghĩ rằng bạn sẽ xúc phạm bất cứ ai, bởi vì đó được xác định là một thiết kế xấu và cố định trong python3: docs.python.org/3/library/functions.html#super
JDI

3

Điều này đã khiến tôi đau đầu hai lần gần đây (tôi biết tôi nên học hỏi từ sai lầm của mình lần đầu tiên) và câu trả lời được chấp nhận đã không giúp ích cho tôi lần nào vì vậy trong khi nó còn mới mẻ trong đầu tôi, tôi nghĩ tôi sẽ gửi câu trả lời của riêng mình để đề phòng bất kỳ ai khác đang gặp phải vấn đề này (hoặc tôi cần điều này một lần nữa trong tương lai).

Trong trường hợp của tôi, vấn đề là tôi đang chuyển một kwarg vào phần khởi tạo của lớp con nhưng trong lớp cha, từ khóa arg sau đó đã được chuyển vào lệnh gọi super ().

Tôi luôn nghĩ rằng những loại này là tốt nhất với một ví dụ:

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

Vì vậy, để giải quyết vấn đề này, tôi chỉ cần thay đổi thứ tự mà tôi thực hiện mọi việc trong phương thức Foo .__ init__; ví dụ:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.