2010-04-28 5 views
8

Toutes les classes dérivées d'une certaine classe de base doivent définir un attribut appelé "path". Au sens de la frappe de canard je pouvais compter sur une définition dans les sous-classes:Passer un paramètre au constructeur de classe de base ou utiliser une variable d'instance?

class Base: 
    pass # no "path" variable here 

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

Une autre possibilité serait d'utiliser le constructeur de la classe de base:

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

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

J'utilise Python 3.1.

Que préférez-vous et pourquoi? Y a-t-il un meilleur moyen?

Répondre

11

En Python 3.0+:
Je voudrais aller avec un paramètre au constructeur de la classe de base comme vous avez dans le second exemple. Comme cela force les classes qui dérivent de Base à fournir la propriété de chemin nécessaire, ce qui documente le fait que la classe a une telle propriété et que les classes dérivées sont nécessaires pour la fournir. Sans cela, vous vous fiez à ce que cela soit dit (et lu) quelque part dans les docstrings de votre classe, bien que cela aide certainement aussi à indiquer dans le docstring ce que signifie la propriété particulière.

En Python 2.6+:
Je voudrais utiliser ni de ce qui précède; à la place, j'utiliser:

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

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

En d'autres termes, il me faudrait un tel paramètre dans le constructeur de la classe de base, car il documente le fait que tous ces types auront/utilisation/besoin de ce paramètre particulier et que le paramètre doit être provieded. Cependant, je n'utiliserais pas super() comme super is somewhat fragile and dangerous in Python, et je ferais aussi Base a new-style class en héritant de l'objet (ou d'une autre nouvelle classe) classe.

+5

Il n'y a rien de fragile à propos de 'super()'. La fragilité est dans la syntaxe 2.x, qui est fixée dans 3.x (que l'OP utilise, comme indiqué par l'appel 'super()'), et l'héritage multiple en général. Il n'y a aucune raison d'appeler la méthode baseclass directement dans Python 3.x, la syntaxe 'super() .__ init (...)' n'est jamais pire et souvent meilleure. –

+0

à en juger par l'utilisation de 'super', je suppose que deamon utilise py3k – SilentGhost

+0

@Thomas Wouters: comment utiliseriez-vous super si vous avez plusieurs classes d'héritage et de base avec des signatures constructeurs différentes? Passer tous les arguments des classes dérivées à toutes les classes de base ressemble à un hack sale, s'appuyer sur des paramètres nommés et laisser les classes de base trier ce dont ils ont besoin n'est pas beaucoup plus agréable. – kriss

Questions connexes