Les classes de base abstraites peuvent toujours être utiles à Python. dans Écrire une classe de base abstraite où je veux que chaque sous-classe ait, disons, un Le défi vient En outre, désirez utiliser Ça va pour une sous-classe simple, mais lorsque vous écrivez un La classe qui a de nombreuses méthodes, l'essai, sauf la chose qui devient un peu encombrant et un peu laide. Y a-t-il un moyen plus élégant de sous-classement des classes de base abstraites? Suis-je juste le faire mal? P> p> spam () code> méthode, je veux écrire quelque chose comme ceci:
super () code>, et pour le faire correctement en l'incluant dans toute la chaîne de sous-classes. Dans ce cas, il semble que je dois envelopper chaque
Super code> appelez comme suit: p>
3 Réponses :
Vous pouvez le faire proprement dans Python 2.6+ avec le ABC Module : < Pré> xxx pré>
la sortie sera p>
Ce n'est pas nécessairement la même chose - on ne peut pas instancer B de votre exemple.
Intéressant! Je n'avais même pas attrapé l'ajout du module code> ABC code>!
@Tomasz aussi intéressant. Quelles sont les implications pour les tests d'unités, alors, si on ne peut pas instancier la classe?
Si vous modifiez le corps de b.foo code> pour être
élever notimpledeError code> il ne jupe pas autour de la question. Il serait toujours utile d'informer le programmeur ", hé, mannequin, vous avez oublié de remplacer cette méthode abstraite!" Je ne suis pas sûr au moment où
abc code> résout vraiment ce problème.
Ah! Je le faisais mal; Vous définissez def foo (): passe code> dans
b code>, puis vous ne pouvez pas instancer les sous-classes avant de remplacer
b.foo code> dans une sous-classe. Fondamentalement, jusqu'à ce que vous remplisiez toutes les méthodes non définies, vous ne pourrez pas instantimer cette sous-classe. Très propre!
N'écrivez pas tout ce code. Une simple inspection de la classe abstraite peut vous faire économiser tout ce code. P>
Si la méthode est abstraite, la sous-classe concrète n'appelle pas super. P>
Si la méthode est concrète, la sous-classe de béton appelle super. P>
C'est une solution simple, sauf si vous allez pour une sorte de héritage coopératif différent. c'est à dire. L'abstrait est A. A <- B, mais vous souhaitez ensuite soutenir l'insertion de C comme un <- C <- B. B n'appelle pas super donc cela ne fonctionne pas correctement. Je pense que le point principal est que lorsque vous utilisez Super, vous devez être conscient de l'héritage coopératif et de vos objectifs pour votre hiérarchie de classe spécifique. Voir ma réponse pour la mise en œuvre de mon exemple ci-dessus.
Le point clé doit comprendre que c'est Par exemple: Résumé est A. A super () code> est destiné à mettre en œuvre une héritage coopérative. Comment les classes coopèrent sont à vous le programmeur.
Super () code> n'est pas magique et ne sait pas exactement ce que vous voulez! Il n'ya pas beaucoup de point dans l'utilisation de Super pour une hiérarchie plate qui n'a pas besoin d'héritage de coopération, de sorte que la suggestion de S. Lott est sur place. Les sous-classes d'utiles peuvent ou non vouloir utiliser
Super () code> en fonction de leurs objectifs :)
B: foo
B: Old __base__ and __mro__:
Base: (<class '__main__.A'>,)
MRO: (<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
B: New __base__ and __mro__:
Base: (<class '__main__.C'>,)
MRO: (<class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
B: foo
C: foo
Cela fait très peu de sens. Vous devez savoir quelles méthodes de superclasse sont implémentées (pour lesquelles
Super code> a du sens) et qui ne sont pas implémentés car ils sont abstraits. Vous pouvez lire la source.
Summer SyntaxError code> est également dans la langue. La question est "Pourquoi écrire tout ce code lorsque la simple inspection de la classe abstraite peut vous faire économiser tout ce code"?
@ S.Lott Ah, compris maintenant. Vous devriez soumettre cela comme une réponse, en passant, parce que c'est.