2011-06-09 6 views
1

Comment pourrais-je initialiser super-classe en python multiples ..multiples super Initialiser classes Python

Par exemple:

class A (B, C): 
    def __init__(self, param): 
     B.__init__(self) 
     C.__init__(self, param) 
    # 
# 
+3

Quel est exactement votre problème? –

+6

Le code que vous montrez fonctionne. Bien sûr, vous le savez, parce que vous l'avez essayé au lieu d'utiliser SO comme interprète. Alors qu'est-ce que vous demandez? – delnan

Répondre

6

Votre code d'origine fonctionne. C'est très clair et lisible. La signature d'appel est claire et vous permet d'instancier A avec A(p) ou A(param=p). Il est également possible d'utiliser super. Il offre la possibilité attrayante pour remplacer les deux appels explicites à B.__init__ et C.__init__ avec un appel à super(A,self).__init__:

class B(object): 
    def __init__(self, **kwargs): 
     print('B') 
     super(B,self).__init__(**kwargs) 

class C(object): 
    def __init__(self, **kwargs): 
     print('C') 
     self.param=kwargs.pop('param',None) 
     super(C,self).__init__(**kwargs) 

class A(B, C): 
    def __init__(self, **kwargs): 
     print('A') 
     super(A,self).__init__(**kwargs) 

a=A(param=1) 

# A 
# B 
# C 

En utilisant super, cependant, exige un rather heavy price:

  1. Les __init__ signatures d'appel de toutes les classes doivent être les mêmes. Depuis A et C ont un argument param mais B n'a pas, vous devez modifier tous trois à utiliser plus ambiguë (mais uniforme!) Argument **kwargs. Ainsi, la signature d'appel n'est plus explicite.

  2. Maintenant A ne peut être instanciée avec A(param=p), et non plus avec A(p).

  3. Pire encore (comme Sven Marnach souligne dans les commentaires), tous les arguments transmis à A doit à un moment donné être sauté hors de kwargs depuis object n'accepte pas d'arguments. Une fois qu'une classe (telle que C) affiche un argument sur de kwargs, aucune autre classe (telle que B) ne peut utiliser le même nom d'argument. Ainsi, la dénomination des arguments nécessite une certaine coordination entre toutes les classes, même si idéalement, B et C devraient être indépendants les uns des autres.

  4. Le code a plus de croute de plaque de chaudière et complication. Il est moins facile de lire .

Ainsi, je préfère généralement super évitant (tout comme votre code d'origine) à moins que le indirection offerte par super l'emporte sur les coûts mentionnés ci-dessus.

+0

Beau résumé. Je voudrais ajouter que c'est en fait * un * diamant d'héritage avec 'object' à sa racine. La chaîne d'appel 'super()' appellera finalement 'object .__ init __ (self, ** kwargs)', donc vous devez vous assurer que tous les arguments ont été supprimés de 'kwargs' à ce moment-là. Cela pose un problème au cas où deux classes auraient besoin d'un argument, et il n'y a pas de véritable solution à ce problème. –

+0

@Sven Marnach: Merci d'avoir signalé ce problème supplémentaire avec 'super'. – unutbu

+0

Je me demande pourquoi super a été appelé à la langue du tout, ce qui rend la chose non explicite alors que ce n'est pas utile pour la plupart des cas d'utilisation. – dashesy