Dziedziczenie w Pythonie: TypeError: object .__ init __ () nie przyjmuje żadnych parametrów

90

Otrzymuję ten błąd:

TypeError: object.__init__() takes no parameters 

podczas uruchamiania kodu nie widzę jednak, co robię źle:

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')
Lucas Kauffman
źródło

Odpowiedzi:

115

W wywołaniu super () wzywasz niewłaściwą nazwę klasy:

class SimpleHelloWorld(IRCReplyModule):

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

Zasadniczo to, do czego zmierzasz, jest __init__klasą bazową obiektu, która nie przyjmuje żadnych parametrów.

Wiem, że jest to trochę zbędne, aby określić klasę, w której już się znajdujesz, dlatego w pythonie3 możesz po prostu zrobić: super().__init__()

jdi
źródło
4
@LucasKauffman: Właściwie nie sądzę, żeby to było głupie z twojej strony. Łatwo może to być myląca koncepcja. Nie winię cię.
jdi
4
Ryzyko urazić wielu Pythonian: To - imho - to okropny projekt języka. Dziękuję za pomoc @jdi!
Johannes Fahrenkrug
4
@JohannesFahrenkrug - nie sądzę, żebyś nikogo uraził, ponieważ został zidentyfikowany jako zły projekt i naprawiony w pythonie3: docs.python.org/3/library/functions.html#super
jdi
3

Niedawno ugryzło mnie to dwa razy (wiem, że powinienem był wyciągnąć wnioski z mojego błędu za pierwszym razem), a zaakceptowana odpowiedź ani razu mi nie pomogła, więc gdy jest świeża w mojej głowie, pomyślałem, że na wszelki wypadek przedstawię własną odpowiedź ktoś inny wpada w to (lub potrzebuję tego ponownie w przyszłości).

W moim przypadku problemem było to, że przekazywałem kwarg do inicjalizacji podklasy, ale w nadklasie to słowo kluczowe arg było następnie przekazywane do wywołania super ().

Zawsze uważam, że tego typu rzeczy są najlepsze na przykładzie:

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

Aby rozwiązać ten problem, wystarczy zmienić kolejność wykonywania czynności w metodzie Foo .__ init__; na przykład:

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
Jan
źródło