web-dev-qa-db-fra.com

Pourquoi pas de décorateur @override en Python pour aider à la lisibilité du code?

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.

20
gnychis

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.

9
Daniel Roseman

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.

9
user2357112