Herencia de Python: TypeError: object .__ init __ () no toma parámetros

90

Me sale este error:

TypeError: object.__init__() takes no parameters 

Sin embargo, cuando ejecuto mi código, realmente no veo lo que estoy haciendo mal aquí:

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
fuente

Respuestas:

115

Estás llamando al nombre de clase incorrecto en tu llamada super ():

class SimpleHelloWorld(IRCReplyModule):

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

Básicamente, lo que está resolviendo es el __init__de la clase base del objeto que no tiene parámetros.

Es un poco redundante, lo sé, tener que especificar la clase en la que ya estás dentro, razón por la cual en python3 puedes hacer lo siguiente: super().__init__()

jdi
fuente
4
@LucasKauffman: En realidad, no creo que sea muy tonto de tu parte. Fácilmente puede ser un concepto confuso. No te culpo
jdi
4
A riesgo de ofender a muchos pitonianos: eso, en mi humilde opinión, es un diseño de lenguaje terrible. ¡Gracias por tu ayuda @jdi!
Johannes Fahrenkrug
4
@JohannesFahrenkrug - No creo que ofendas a nadie, porque eso se identificó como un mal diseño y se solucionó en python3: docs.python.org/3/library/functions.html#super
jdi
3

Esto me ha mordido dos veces recientemente (sé que debería haber aprendido de mi error la primera vez) y la respuesta aceptada no me ha ayudado en ninguna ocasión, así que aunque está fresca en mi mente, pensé que enviaría mi propia respuesta por si acaso. alguien más se está encontrando con esto (o lo necesito nuevamente en el futuro).

En mi caso, el problema era que estaba pasando un kwarg a la inicialización de la subclase, pero en la superclase esa palabra clave arg se pasaba a la llamada super ().

Siempre creo que este tipo de cosas son mejores con un ejemplo:

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

Entonces, para resolver esto, solo necesito alterar el orden en que hago las cosas en el método Foo .__ init__; p.ej:

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
Juan
fuente