2012-05-02 6 views
16

Mi sconcerta come non riesca a trovare una spiegazione chiara di questo ovunque. Perché e quando è necessario chiamare il metodo della classe base all'interno del metodo stesso nome della classe figlio?ereditarietà Python - chiamando i metodi della classe base all'interno della classe figlio?

class Child(Base): 
    def __init__(self): 
     Base.__init__(self) 

    def somefunc(self): 
     Base.somefunc(self) 

Sto supponendo che lo faccia quando non si desidera sovrascrivere completamente il metodo nella classe base. è davvero tutto quello che c'è da fare?

risposta

2

Dipende completamente dalla classe e dal metodo.

Se si desidera eseguire un'operazione prima/dopo l'esecuzione del metodo di base o chiamarla con argomenti diversi, è ovviamente necessario chiamare il metodo di base nel metodo della sottoclasse.

Se si desidera sostituire l'intero metodo, ovviamente non lo si chiama.

+0

Come nota a margine, tuttavia, si dovrebbe sempre chiamare la classe genitrice ''__init__'. – Amber

13

Di solito, lo si fa quando si desidera estendere la funzionalità modificando, ma non sostituendo completamente un metodo di classe base. defaultdict è un buon esempio di questo:

class DefaultDict(dict): 
    def __init__(self, default): 
     self.default = default 
     dict.__init__(self) 

    def __getitem__(self, key): 
     try: 
      return dict.__getitem__(self, key) 
     except KeyError: 
      result = self[key] = self.default() 
      return result 

Nota che il modo appropriato per farlo è quello di use super instead of directly calling the base class. Così:

class BlahBlah(someObject, someOtherObject): 
    def __init__(self, *args, **kwargs): 
     #do custom stuff 
     super(BlahBlah, self).__init__(*args, **kwargs) # now call the parent class(es) 
+0

Cosa c'è di bello in queste funzioni "super"? – user1369281

+5

@ user1369281: Beh, non sono sempre fantastici. Tuttavia, se li usi in modo coerente, rendono gli alberi ereditari molto più facili da utilizzare. Cosa succede se, ad esempio, volevo cambiare il mio 'defaultdict' in un _ordered_ dict predefinito. Se usassi 'super()', la sola cosa che dovrei cambiare nel mio codice sarebbe la definizione della classe. Tutti quei 'super' si riferiscono automaticamente a qualsiasi classe base da cui erediti la mia attuale classe. Facilita la programmazione della scatola nera. –

+0

Mi piace perché ti ricorda (o insegna) che la tua classe può ereditare più classi. Quindi se la tua classe genitore proviene da una lib non puoi modificare e non ereditare già l'oggetto, puoi semplicemente aggiungere 'object' alla tua classe. – casey