Héritage Python: TypeError: object .__ init __ () ne prend aucun paramètre

90

J'obtiens cette erreur:

TypeError: object.__init__() takes no parameters 

lors de l'exécution de mon code, je ne vois pas vraiment ce que je fais de mal ici:

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
la source

Réponses:

115

Vous appelez le mauvais nom de classe dans votre appel super ():

class SimpleHelloWorld(IRCReplyModule):

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

Essentiellement, ce que vous résolvez est la __init__classe de base d'objet qui ne prend aucun paramètre.

C'est un peu redondant, je sais, de devoir spécifier la classe dans laquelle vous êtes déjà à l'intérieur, c'est pourquoi en python3 vous pouvez simplement faire: super().__init__()

jdi
la source
4
@LucasKauffman: En fait, je ne pense pas que ce soit très ridicule de ta part. Cela peut facilement être un concept déroutant. Je ne te blâme pas.
jdi
4
Au risque d'offenser de nombreux Pythoniens: c'est - à mon humble avis - une conception de langage terrible. Merci pour votre aide @jdi!
Johannes Fahrenkrug
4
@JohannesFahrenkrug - Je ne pense pas que vous offenseriez qui que ce soit, car cela a été identifié comme une mauvaise conception et corrigé dans python3: docs.python.org/3/library/functions.html#super
jdi
3

Cela m'a mordu deux fois récemment (je sais que j'aurais dû apprendre de mon erreur la première fois) et la réponse acceptée ne m'a pas aidé non plus, alors même si c'est frais dans mon esprit, j'ai pensé que je soumettrais ma propre réponse au cas où quelqu'un d'autre se heurte à cela (ou j'en ai encore besoin à l'avenir).

Dans mon cas, le problème était que je passais un kwarg dans l'initialisation de la sous-classe, mais dans la superclasse, ce mot-clé arg était ensuite passé dans l'appel super ().

Je pense toujours que ces types de choses sont mieux avec un exemple:

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

Donc, pour résoudre ce problème, j'ai juste besoin de modifier l'ordre dans lequel je fais les choses dans la méthode Foo .__ init__; par exemple:

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
la source