2014-11-15 13 views
6

(non sono in grado di trovare un punto di riferimento da nessuna parte su questa materia dopo un po 'Googling.)Quando chiamare Python super() .__ init __()?

Lo scenario può essere chiaramente dimostrato con questo esempio di codice breve:

class X: 
    def __init__(self, stuff): 
     self.__stuff = stuff 

class Y(X): 
    def __init__(self, stuff): 
     # Is it safe to execute statements before calling super.__init__()? 
     new_stuff = self.call_another_method(stuff) 
     super(Y, self).__init__(new_stuff) 

Utilizzando CPython 3.x, quanto sopra esempio di codice funziona - supponendo che esista call_another_method(). Questo stile di codifica è generalmente sicuro, ma disapprovato o considerato unpitonico? Non riesco a trovare consigli su questo argomento.

Perché mi interessa?

Il mio background deriva da linguaggi di programmazione orientati agli oggetti più tradizionali come C++, C# e Java, dove "super" deve essere chiamato rigorosamente come prima istruzione in un costruttore sottoclasse - ignorando il caso implicito zero-argument.

Se è importante, sono un giovane pitone: 3+, per favore.

+1

IIRC, in Python 3.x, non hai più bisogno di chiamare 'super (ClassName, self)', 'super()' funziona da solo. –

+0

L'unica cosa che 'super' in Java e Python hanno in comune è il nome. Java 'super' è una parola chiave che fa riferimento alla (sola) classe base; Python 'super' è una funzione built-in che, utilizzando i suoi argomenti, restituisce un oggetto che funge da proxy per alcune classi nell'ordine di risoluzione dei metodi di un oggetto. – chepner

+0

@ChinmayKanchi: Grazie per il suggerimento. Aggiornerò il mio codice andando avanti! – kevinarpe

risposta

9

Sì, è perfettamente sicuro chiamare altre cose prima dello super(). Python non imposta un ordine, e ci sono molti casi d'uso per questo.

Nota che la chiamata super().__init__() è solo un'altra espressione in Python, non è un costrutto di sintassi. È possibile utilizzare anche i metodi esterni super(), a condizione di passare gli argomenti giusti.

Nel tuo caso, è possibile omettere il tipo e di istanza argomenti, Python 3 recupererà questi per voi quando super() è chiamato senza argomenti, perché si sta utilizzando in una funzione definita all'interno di una classe:

class Y(X): 
    def __init__(self, stuff): 
     new_stuff = self.call_another_method(stuff) 
     # super(Y, self) is implicit here: 
     super().__init__(new_stuff) 
+1

Si noti che quando in C++ non si chiama esplicitamente il constuctor della base, il suo costruttore predefinito verrà chiamato implicitamente. In Python, se non lo chiami in modo esplicito, non verrà chiamato affatto. "_Explicit è meglio di implicito._" – GingerPlusPlus

+0

@GingerPlusPlus: Ja. Lo stesso per C# e Java (e molti altri). – kevinarpe