Quelle est la différence entre la classe abstraite et l'interface en Python?
Quelle est la différence entre la classe abstraite et l'interface en Python?
Ce que vous verrez parfois est le suivant:
class Abstract1( object ):
"""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) de 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, ce sera aussi une classe abstraite. Les seules différences seraient dans l'intention déclarée dans la docstring.
Et la différence entre l'abstrait et l'interface est une chose à couper les cheveux lorsque vous avez tapé du canard.
Java utilise des interfaces car il n'a pas d'héritage multiple.
Parce que Python a un héritage multiple, vous pouvez également voir quelque chose comme ça
class SomeAbstraction( object ):
pass # lots of stuff - but missing something
class Mixin1( object ):
def something( self ):
pass # one implementation
class Mixin2( object ):
def something( self ):
pass # another
class Concrete1( SomeAbstraction, Mixin1 ):
pass
class Concrete2( SomeAbstraction, Mixin2 ):
pass
Cela utilise une sorte de superclasse abstraite avec des mixins pour créer des sous-classes concrètes disjointes.
NotImplementedError("Class %s doesn't implement aMethod()" % (self.__class__.__name__))
est un message d'erreur plus informatif :)Une interface, pour un objet, est un ensemble de méthodes et d'attributs sur cet objet.
En Python, nous pouvons utiliser une classe de base abstraite pour définir et appliquer une interface.
Utilisation d'une classe de base abstraite
Par exemple, disons que nous voulons utiliser l'une des classes de base abstraites du
collections
module:Si nous essayons de l'utiliser, nous obtenons un
TypeError
car la classe que nous avons créée ne prend pas en charge le comportement attendu des ensembles:Nous sommes donc tenus de mettre en œuvre au moins
__contains__
,__iter__
et__len__
. Utilisons cet exemple d'implémentation de la documentation :Implémentation: création d'une classe de base abstraite
Nous pouvons créer notre propre classe de base abstraite en définissant la métaclasse sur
abc.ABCMeta
et en utilisant leabc.abstractmethod
décorateur sur les méthodes pertinentes. La métaclasse ajoutera les fonctions décorées à l'__abstractmethods__
attribut, empêchant l'instanciation jusqu'à ce qu'elles soient définies.Par exemple, "effable" est défini comme quelque chose qui peut être exprimé en mots. Supposons que nous voulions définir une classe de base abstraite qui soit effable, en Python 2:
Ou en Python 3, avec le léger changement de déclaration de métaclasse:
Maintenant, si nous essayons de créer un objet effable sans implémenter l'interface:
et essayez de l'instancier:
On nous dit que nous n'avons pas terminé le travail.
Maintenant, si nous nous conformons en fournissant l'interface attendue:
on peut alors utiliser la version concrète de la classe dérivée de la classe abstraite:
Il y a d'autres choses que nous pourrions faire avec cela, comme enregistrer des sous-classes virtuelles qui implémentent déjà ces interfaces, mais je pense que cela dépasse le cadre de cette question. Les autres méthodes présentées ici devraient adapter cette méthode en utilisant le
abc
module.Conclusion
Nous avons démontré que la création d'une classe de base abstraite définit des interfaces pour des objets personnalisés en Python.
la source
Python> = 2.6 a des classes de base abstraites .
Il y a aussi le module Zope Interface , qui est utilisé par des projets en dehors de zope, comme twisted. Je ne le connais pas vraiment, mais il y a une page wiki ici 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 plus de détails).
la source
Python n'a pas vraiment de concept.
Il utilise le typage 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 aucun moyen explicite de marquer une méthode comme 'virtuelle pure', donc la classe n'est pas vraiment abstraite.
Python> = 2.6: des classes de base abstraites existent ( http://docs.python.org/library/abc.html ). Et vous permettent de spécifier des méthodes qui doivent être implémentées dans des sous-classes. Je n'aime pas beaucoup la syntaxe, mais la fonctionnalité est là. La plupart du temps, il est probablement préférable d'utiliser la frappe de canard du côté client «utilisant».
la source
D'une manière plus simple à expliquer: Une interface est un peu comme un moule à muffins vide. Il s'agit d'un fichier de classe avec un ensemble de définitions de méthodes sans code.
Une classe abstraite est la même chose, mais toutes les fonctions n'ont pas besoin d'être vides. Certains peuvent avoir du code. Ce n'est pas strictement vide.
Pourquoi différencier: 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, car il n'y a pas de code. Surtout si vous travaillez avec des programmeurs Java habitués au terme.
la source
En général, les interfaces sont utilisées uniquement 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 une classe peut utiliser une méthode ou un ensemble de méthodes particulier. Toujours dans ces langages à héritage unique, les classes abstraites sont utilisées pour avoir des variables de classe définies en plus d’aucune ou plusieurs méthodes, ou pour exploiter le modèle d’héritage unique pour limiter la gamme de classes qui pourraient utiliser un ensemble de méthodes.
Les langages qui prennent en charge le modèle à héritage multiple ont tendance à utiliser uniquement des classes ou des classes de base abstraites et non des interfaces. Étant donné que Python prend en charge l'héritage multiple, il n'utilise pas d'interfaces et vous souhaitez utiliser des classes de base ou des classes de base abstraites.
http://docs.python.org/library/abc.html
la source
Les classes abstraites sont des classes qui contiennent une ou plusieurs méthodes abstraites. En plus des méthodes abstraites, les classes abstraites peuvent avoir des méthodes statiques, de classe et d'instance. Mais en cas d'interface, il n'aura que des méthodes abstraites pas les autres. Par conséquent, il n'est pas obligatoire d'hériter de la classe abstraite mais il est obligatoire d'hériter de l'interface.
la source
Pour être complet, nous devons mentionner PEP3119 où ABC a été introduit et comparé aux interfaces, et le commentaire original de Talin .
La classe abstraite n'est pas une interface parfaite:
Mais si vous envisagez de l'écrire à votre façon:
vous réaliserez assez rapidement que vous inventez la roue pour finalement atteindre
abc.ABCMeta
abc.ABCMeta
a été proposé comme un ajout utile de la fonctionnalité d'interface manquante, et c'est assez juste dans un langage comme python.Certes, il a pu être amélioré davantage lors de l'écriture de la version 3, et en ajoutant une nouvelle syntaxe et un concept d'interface immuable ...
Conclusion:
la source