J'ai utilisé des classes abstraites dans Python avec ABCMeta
. Lorsque vous écrivez une méthode abstraite, vous la marquez avec le décorateur @abstractmethod
. Une chose que j'ai trouvée étrange (et contrairement à d'autres langages) est que lorsque la sous-classe remplace la méthode de super-classe, aucun décorateur comme @override
est fourni. Quelqu'un sait-il quelle pourrait être la logique derrière tout cela?
Cela rend légèrement confus pour quelqu'un qui lit le code d'établir rapidement quelles méthodes remplacent/implémentent des méthodes abstraites par rapport aux méthodes qui n'existent que dans la sous-classe.
Vous confondez Python décorateurs avec Java annotations. Malgré la syntaxe similaire, ce sont des choses complètement différentes. A Java annotation est une instruction pour le compilateur. Mais un décorateur Python est un code exécutable qui fait quelque chose de concret: il enveloppe la fonction dans une autre fonction qui peut changer ce qu'elle fait. C'est le cas pour la méthode abstraite juste autant que n'importe quel autre décorateur; il fait quelque chose, à savoir dire à l'ABC qu'il existe une méthode qui doit être remplacée.
Le problème avec l'ajout de @override
est qu'au moment de la définition de la méthode, le décorateur n'a aucun moyen de dire si la méthode remplace réellement une autre méthode. Il n'a pas accès aux classes parentes (ou à la classe actuelle, qui n'existe même pas encore!).
Si vous souhaitez ajouter @override
, les @override
le décorateur ne peut pas faire de vérification de remplacement. Vous avez alors deux options. Soit il n'y a is pas de vérification de priorité, auquel cas @override
n'est pas mieux qu'un commentaire, ou le constructeur type
doit connaître spécifiquement @override
et vérifiez-le au moment de la création de la classe. Une fonctionnalité pratique comme @override
ne devrait vraiment pas avoir besoin de compliquer les parties centrales de l'implémentation du système de type comme ça. De plus, si vous mettez accidentellement @override
sur une non-méthode, le bogue restera non détecté jusqu'à ce que vous essayiez d'appeler la fonction décorée et d'obtenir une étrange TypeError.