Ereditarietà Python: TypeError: object .__ init __ () non accetta parametri


90

Ottengo questo errore:

TypeError: object.__init__() takes no parameters 

quando eseguo il mio codice, non vedo davvero cosa sto facendo di sbagliato qui:

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

Risposte:


115

Stai chiamando il nome della classe sbagliato nella chiamata super ():

class SimpleHelloWorld(IRCReplyModule):

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

Essenzialmente ciò che stai risolvendo è la __init__classe base dell'oggetto che non accetta parametri.

È un po 'ridondante, lo so, dover specificare la classe in cui sei già all'interno, motivo per cui in python3 puoi semplicemente fare: super().__init__()


4
@ LucasKauffman: In realtà non penso che sia molto sciocco da parte tua. Può facilmente essere un concetto confuso. Non ti biasimo.
jdi

4
A rischio di offendere molti Pythonians: Quello - imho - è un linguaggio terribile. Grazie per il tuo aiuto @jdi!
Johannes Fahrenkrug

4
@JohannesFahrenkrug - Non penso che offenderesti nessuno, perché è stato identificato come un cattivo design e corretto in python3: docs.python.org/3/library/functions.html#super
jdi

3

Questo mi ha morso due volte di recente (so che avrei dovuto imparare dal mio errore la prima volta) e la risposta accettata non mi ha aiutato neanche la volta, quindi mentre è fresca nella mia mente ho pensato di inviare la mia risposta per ogni evenienza qualcun altro si sta imbattendo in questo (o ne ho bisogno di nuovo in futuro).

Nel mio caso il problema era che stavo passando un kwarg nell'inizializzazione della sottoclasse, ma nella superclasse quella parola chiave arg veniva poi passata nella chiamata super ().

Penso sempre che questi tipi di cose siano migliori con un esempio:

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

Quindi per risolvere questo problema ho solo bisogno di modificare l'ordine in cui faccio le cose nel metodo Foo .__ init__; per esempio:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.