Python-Vererbung: TypeError: Objekt .__ init __ () akzeptiert keine Parameter

89

Ich erhalte diesen Fehler:

TypeError: object.__init__() takes no parameters 

Wenn ich meinen Code ausführe, sehe ich hier allerdings nicht wirklich, was ich falsch mache:

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
quelle

Antworten:

114

Sie rufen in Ihrem super () -Aufruf den falschen Klassennamen auf:

class SimpleHelloWorld(IRCReplyModule):

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

Im Wesentlichen lösen Sie __init__die Objektbasisklasse auf, die keine Parameter akzeptiert.

Ich weiß, es ist ein bisschen überflüssig, die Klasse angeben zu müssen, in der Sie sich bereits befinden. Deshalb können Sie in Python3 einfach Folgendes tun: super().__init__()

jdi
quelle
4
@ LucasKauffman: Eigentlich finde ich es nicht sehr dumm von dir. Es kann leicht ein verwirrendes Konzept sein. Ich beschuldige dich nicht.
JDI
4
Auf die Gefahr, viele Pythonianer zu beleidigen: Das - imho - ist schreckliches Sprachdesign. Vielen Dank für Ihre Hilfe @jdi!
Johannes Fahrenkrug
4
@JohannesFahrenkrug - Ich glaube nicht, dass Sie jemanden beleidigen würden, da dies als schlechtes Design identifiziert und in python3 behoben wurde: docs.python.org/3/library/functions.html#super
jdi
3

Dies hat mich in letzter Zeit zweimal gebissen (ich weiß, ich hätte beim ersten Mal aus meinem Fehler lernen sollen) und die akzeptierte Antwort hat mir auch nicht geholfen. Während es in meinem Kopf frisch ist, dachte ich, ich würde meine eigene Antwort für alle Fälle einreichen jemand anderes stößt darauf (oder ich brauche das in Zukunft wieder).

In meinem Fall bestand das Problem darin, dass ich ein kwarg an die Initialisierung der Unterklasse übergeben habe, aber in der Oberklasse wurde dieses Schlüsselwort arg dann an den Aufruf von super () übergeben.

Ich denke immer, dass diese Art von Dingen am besten mit einem Beispiel ist:

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

Um dies zu beheben, muss ich nur die Reihenfolge ändern, in der ich Dinge in der Foo .__ init__ -Methode mache. z.B:

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
John
quelle