Quelle est la différence entre une classe abstraite et une interface en Python ?
S. Lott, voulez-vous dire qu'en raison du typage des canards, la distinction entre has-a (interface) et is-a (héritage) n'est pas substantielle ?
Quelle est la différence entre une classe abstraite et une interface en Python ?
Ce que vous verrez parfois est le suivant :
class Abstract1:
"""Some description that tells you it's abstract,
often listing the methods you're expected to supply."""
def aMethod(self):
raise NotImplementedError("Should have implemented this")
Parce que Python n'a pas (et n'a pas besoin) d'un contrat d'interface formel, la distinction de style Java entre abstraction et interface n'existe pas. Si quelqu'un fait l'effort de définir une interface formelle, il s'agira également d'une classe abstraite. Les seules différences seraient dans l'intention déclarée dans la docstring.
Et la différence entre abstrait et interface est une chose épineuse lorsque vous avez la typographie des canards.
Java utilise des interfaces parce qu'il n'a pas d'héritage multiple.
Comme Python a un héritage multiple, vous pouvez aussi voir quelque chose comme ceci
class SomeAbstraction:
pass # lots of stuff - but missing something
class Mixin1:
def something(self):
pass # one implementation
class Mixin2:
def something(self):
pass # another
class Concrete1(SomeAbstraction, Mixin1):
pass
class Concrete2(SomeAbstraction, Mixin2):
pass
Elle utilise une sorte de superclasse abstraite avec des mixins pour créer des sous-classes concrètes qui sont disjointes.
S. Lott, voulez-vous dire qu'en raison du typage des canards, la distinction entre has-a (interface) et is-a (héritage) n'est pas substantielle ?
La différence entre l'abstrait et l'interface est une chose épineuse lorsque vous avez la saisie des canards. Je ne sais pas ce que signifie "substantiel". C'est "réel" - ça a de la substance - du point de vue de la conception. Mais du point de vue du langage, il peut ne pas y avoir de support. Vous pourriez adopter des conventions pour distinguer entre une classe abstraite et une définition de classe d'interface en Python.
@L.DeLeo - Êtes-vous sûr que votre notion de has-a vs. is-a est correcte ? Je considère généralement la distinction comme has-a = variable membre vs. is-a = héritage (classe parente ou interface). Pensez à Comparable ou List en Java ; ce sont des relations is-a, qu'il s'agisse d'interfaces ou de classes abstraites.
Python >= 2.6 a Classes de base abstraites .
Les classes de base abstraites (en abrégé ABC) complètent le typage des canards en fournissant un moyen de définir des interfaces lorsque d'autres techniques comme hasattr() seraient maladroites. Python est livré avec de nombreux ABC intégrés pour les structures de données (dans le module collections), les nombres (dans le module numbers) et les streams (dans le module io). Vous pouvez créer votre propre ABC avec le module abc.
Il y a aussi le Interface Zope qui est utilisé par des projets extérieurs à zope, comme twisted. Je ne suis pas vraiment familier avec lui, mais il y a une page wiki aquí qui pourrait aider.
En général, vous n'avez pas besoin du concept de classes abstraites, ou d'interfaces en python (édité - voir la réponse de S.Lott pour les détails).
Python ne possède pas vraiment ces deux concepts.
Il utilise dactylographie du canard ce qui a supprimé le besoin d'interfaces (au moins pour l'ordinateur :-))
Python <= 2.5 : Les classes de base existent évidemment, mais il n'y a pas de moyen explicite de marquer une méthode comme 'pure virtual', donc la classe n'est pas vraiment abstraite.
Python >= 2.6 : Les classes de base abstraites font existe ( http://docs.python.org/library/abc.html ). Et vous permettent de spécifier les méthodes qui doivent être implémentées dans les sous-classes. Je n'aime pas trop la syntaxe, mais la fonctionnalité est là. La plupart du temps, il est probablement préférable d'utiliser le typage en canard du côté du client "utilisateur".
Python 3.0 ajoute de véritables classes de base abstraites. Elles sont utilisées dans le module collections ainsi qu'à d'autres endroits. docs.python.org/3.0/library/abc.html
Une référence sur les raisons pour lesquelles la typographie des canards supprime le besoin d'interfaces serait utile. Il ne me semble pas évident que le duck typing, que je comprends comme la capacité de "poke" n'importe quelle méthode ou attribut sur n'importe quel objet, signifierait que vous n'avez pas besoin de spécifier les comportements requis (et d'obtenir du compilateur qu'il vous rappelle de les implémenter), ce qui est la façon dont je comprends les classes de base abstraites.
D'une manière plus basique pour expliquer : Une interface est un peu comme un moule à muffins vide. C'est un fichier de classe avec un ensemble de définitions de méthodes qui n'ont pas de code.
Une classe abstraite est la même chose, mais toutes les fonctions n'ont pas besoin d'être vides. Certaines peuvent avoir du code. Ce n'est pas strictement vide.
Pourquoi faire la différence : Il n'y a pas beaucoup de différence pratique en Python, mais au niveau de la planification d'un grand projet, il pourrait être plus courant de parler d'interfaces, puisqu'il n'y a pas de code. Surtout si vous travaillez avec des programmeurs Java qui sont habitués à ce terme.
En général, les interfaces ne sont utilisées que dans les langages qui utilisent le modèle de classe à héritage unique. Dans ces langages à héritage unique, les interfaces sont généralement utilisées si n'importe quelle classe peut utiliser une méthode particulière ou un ensemble de méthodes. Toujours dans ces langages à héritage unique, les classes abstraites sont utilisées soit pour avoir des variables de classe définies en plus d'une ou plusieurs méthodes, soit pour exploiter le modèle d'héritage unique afin de limiter la gamme de classes qui pourraient utiliser un ensemble de méthodes.
Les langages qui prennent en charge le modèle d'héritage multiple ont tendance à utiliser uniquement des classes ou des classes de base abstraites et non des interfaces. Puisque Python supporte l'héritage multiple, il n'utilise pas d'interfaces et vous voudriez utiliser des classes de base ou des classes de base abstraites.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.