Спадкування Python: TypeError: object .__ init __ () не приймає жодних параметрів


90

Я отримую цю помилку:

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

Відповіді:


115

Ви викликаєте неправильне ім’я класу у своєму дзвінку 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
Ризик образити багатьох пітонців: Це - imho - це жахливий мовний дизайн. Дякуємо за допомогу @jdi!
Йоханнес Фаренкруг,

4
@JohannesFahrenkrug - Я не думаю, що ти когось образиш, тому що це було визнано як поганий дизайн і виправлено в python3: docs.python.org/3/library/functions.html#super
jdi

3

Нещодавно це мене вкусило двічі (я знаю, що з першої помилки повинен був навчитися з першого разу), і прийнята відповідь мені ніколи не допомогла, тому, поки вона свіжа в моїй свідомості, я думав, що подаю свою власну відповідь про всяк випадок хтось інший стикається з цим (або мені це потрібно знову в майбутньому).

У моєму випадку проблема полягала в тому, що я передавав kwarg в ініціалізацію підкласу, але в суперкласі це ключове слово arg потім передавалось у виклик 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.