2010-04-28 13 views
8

Tutte le classi derivate da una determinata classe base devono definire un attributo chiamato "percorso". Nel senso di battitura anatra potevo dipendere dalle definizioni nelle sottoclassi:Passare il parametro al costruttore della classe base o utilizzare la variabile di istanza?

class Base: 
    pass # no "path" variable here 

def Sub(Base): 
    def __init__(self): 
     self.path = "something/" 

ulteriore possibilità sarebbe quella di utilizzare il costruttore della classe base:

class Base: 
    def __init__(self, path): 
     self.path = path 

def Sub(Base): 
    def __init__(self): 
     super().__init__("something/") 

io uso Python 3.1.

Cosa preferisci e perché? C'è un modo migliore?

risposta

11

In Python 3.0+:
vorrei andare con un parametro al costruttore della classe base, come si ha nel secondo esempio. Poiché questo forza le classi che derivano da Base per fornire la proprietà path necessaria, che documenta il fatto che la classe ha una tale proprietà e che le classi derivate sono necessarie per fornirla. Senza di esso, ci si potrebbe basare su questo essere dichiarato (e letto) da qualche parte nelle docstring della classe, anche se certamente aiuta anche a dichiarare nella docstring cosa significhi la particolare proprietà.

In Python 2.6 +:
Vorrei utilizzare nessuno dei sopra; invece vorrei utilizzare:

class Base(object): 
    def __init__(self,path): 
     self.path=path; 

class Sub(Base): 
    def __init__(self): 
     Base.__init__(self,"something/") 

In altre parole, richiederebbe un tale parametro nel costruttore della classe base, in quanto documenta il fatto che tutti questi tipi avranno/uso/bisogno di quel parametro particolare, e che il parametro deve essere dimostrato. Tuttavia, non utilizzerei super() come super is somewhat fragile and dangerous in Python e creerei anche Base a new-style class ereditando dalla classe object (o da qualche altro nuovo stile).

+5

Non c'è niente di fragile in 'super()'. La fragilità è nella sintassi 2.x, che è fissata in 3.x (che l'OP sta usando, come mostrato dalla chiamata 'super()'), e l'ereditarietà multipla in generale. Non c'è alcun motivo per cui sia necessario chiamare il metodo di baseclass direttamente in Python 3.x, la sintassi 'super() .__ init (...)' non è mai peggiore e spesso migliore. –

+0

a giudicare dall'uso di 'super', immagino che deamon stia usando py3k – SilentGhost

+0

@Thomas Wouters: come utilizzeresti super se tutte le classi di ereditarietà e di base multiple con diverse firme del costruttore? Passare tutti gli argomenti delle classi derivate a tutte le classi base appare come un trucco sporco, basandosi su parametri denominati e lasciare che le classi di base risolvano ciò di cui hanno bisogno non è molto più bello. – kriss

Problemi correlati