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)
#
#
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)
#
#
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:
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.
Maintenant A
ne peut être instanciée avec A(param=p)
, et non plus avec A(p)
.
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.
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.
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. –
@Sven Marnach: Merci d'avoir signalé ce problème supplémentaire avec 'super'. – unutbu
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
Quel est exactement votre problème? –
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