Formation gratuite Python
Les interfaces jouent un rôle important en génie logiciel. À mesure qu'une application se développe, les mises à jour et les modifications apportées à la base de code deviennent plus difficiles à gérer. Plus souvent qu'autrement, vous vous retrouvez avec des cours qui se ressemblent beaucoup mais qui ne sont pas liés, ce qui peut entraîner une certaine confusion. Dans ce didacticiel, vous verrez comment utiliser un Interface Python pour aider à déterminer quelle classe vous devez utiliser pour résoudre le problème actuel.
Dans ce didacticiel, vous pourrez:
- Comprendre comment les interfaces fonctionnent et les mises en garde de la création d'interface Python
- Comprendre l'utilité des interfaces dans un langage dynamique comme Python
- Mettre en place une interface informelle Python
- Utilisation
abc.ABCMeta
et@ abc.abstractmethod
pour implémenter une interface formelle Python
Les interfaces en Python sont gérées différemment de la plupart des autres langages et leur complexité de conception peut varier. À la fin de ce didacticiel, vous aurez une meilleure compréhension de certains aspects du modèle de données Python, ainsi que de la façon dont les interfaces en Python se comparent à celles des langages tels que Java, C ++ et Go.
Bonus gratuit: 5 réflexions sur la maîtrise de Python, un cours gratuit pour les développeurs Python qui vous montre la feuille de route et l'état d'esprit dont vous aurez besoin pour faire passer vos compétences Python au niveau supérieur.
Présentation de l'interface Python
À un niveau élevé, une interface agit comme un plan pour concevoir des cours. Comme les classes, les interfaces définissent des méthodes. Contrairement aux classes, ces méthodes sont abstraites. Un méthode abstraite est celui que l'interface définit simplement. Il n'implémente pas les méthodes. Cela se fait par classes, qui mettre en place l'interface et donner un sens concret aux méthodes abstraites de l'interface.
L'approche de Python pour la conception d'interfaces est quelque peu différente par rapport à des langages tels que Java, Go et C ++. Ces langues ont toutes un interface
mot-clé, contrairement à Python. Python s'écarte en outre des autres langages sous un autre aspect. Il n’exige pas que la classe qui implémente l’interface définisse toutes les méthodes abstraites de l’interface.
Interfaces informelles
Dans certaines circonstances, vous n'aurez peut-être pas besoin des règles strictes d'une interface Python formelle. La nature dynamique de Python vous permet de mettre en œuvre un interface informelle. Une interface Python informelle est une classe qui définit des méthodes qui peuvent être remplacées, mais il n'y a pas d'application stricte.
Dans l'exemple suivant, vous prendrez le point de vue d'un ingénieur de données qui doit extraire du texte de différents types de fichiers non structurés, tels que des PDF et des e-mails. Vous allez créer une interface informelle qui définit les méthodes qui figureront à la fois dans PdfParser
et EmlParser
cours concrets:
classe InformalParserInterface:
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "Charger le fichier pour extraire le texte." ""
passer
def extract_text(soi, nom_fichier complet: str) -> dicter:
"" "Extraire le texte du fichier actuellement chargé." ""
passer
InformalParserInterface
définit les deux méthodes .load_data_source ()
et .extract_text ()
. Ces méthodes sont définies mais non implémentées. L'implémentation aura lieu une fois que vous aurez créé classes de béton qui héritent de InformalParserInterface
.
Comme vous pouvez le voir, InformalParserInterface
semble identique à une classe Python standard. Vous comptez sur la saisie de canard pour informer les utilisateurs qu'il s'agit d'une interface et doit être utilisée en conséquence.
Remarque: Je n’ai pas entendu parler de dactylographie de canard? Ce terme dit que si vous avez un objet qui ressemble à un canard, marche comme un canard et charlatan comme un canard, alors ce doit être un canard! Pour en savoir plus, consultez Duck Typing.
Avec la saisie de canard à l'esprit, vous définissez deux classes qui implémentent le InformalParserInterface
. Pour utiliser votre interface, vous devez créer une classe concrète. UNE classe de béton est une sous-classe de l'interface qui fournit une implémentation des méthodes de l'interface. Vous allez créer deux classes concrètes pour implémenter votre interface. Le premier est PdfParser
, que vous utiliserez pour analyser le texte des fichiers PDF:
classe PdfParser(InformalParserInterface):
"" "Extraire le texte d'un PDF" ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text(soi, full_file_path: str) -> dicter:
"" "Remplace InformalParserInterface.extract_text" ""
passer
La mise en œuvre concrète de InformalParserInterface
vous permet désormais d'extraire du texte à partir de fichiers PDF.
La deuxième classe concrète est EmlParser
, que vous utiliserez pour analyser le texte des e-mails:
classe EmlParser(InformalParserInterface):
"" "Extraire le texte d'un e-mail" ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text_from_email(soi, full_file_path: str) -> dicter:
"" "Une méthode définie uniquement dans EmlParser.
Ne remplace pas InformalParserInterface.extract_text
"" "
passer
La mise en œuvre concrète de InformalParserInterface
vous permet désormais d'extraire du texte à partir de fichiers e-mail.
Jusqu'à présent, vous en avez défini deux implémentations concrètes du InformalPythonInterface
. Notez cependant que EmlParser
ne parvient pas à définir correctement .extract_text ()
. Si vous deviez vérifier si EmlParser
met en oeuvre InformalParserInterface
, vous obtiendrez alors le résultat suivant:
# Vérifiez si PdfParser et EmlParser implémentent InformalParserInterface
issubclass(PdfParser, InformalParserInterface) # Vrai
issubclass(EmlParser, InformalParserInterface) # Vrai
Cela reviendrait Vrai
, ce qui pose un peu de problème car il viole la définition d'une interface!
Maintenant, vérifiez le ordre de résolution de méthode (MRO) de PdfParser
et EmlParser
. Cela vous indique les superclasses de la classe en question, ainsi que l'ordre dans lequel elles sont recherchées pour exécuter une méthode. Vous pouvez afficher le MRO d'une classe à l'aide de la méthode dunder cls .__ mro__
:
# (__main __. PdfParser, __main __. InformalParserInterface, objet)
PdfParser.__mro__
# (__main __. EmlParser, __main __. InformalParserInterface, objet)
EmlParser.__mro__
De telles interfaces informelles conviennent parfaitement aux petits projets où seuls quelques développeurs travaillent sur le code source. Cependant, à mesure que les projets s'agrandissent et que les équipes s'agrandissent, les développeurs peuvent passer d'innombrables heures à rechercher des erreurs logiques difficiles à trouver dans la base de code!
Utilisation de métaclasses
Idéalement, vous voudriez issubclass (EmlParser, InformalParserInterface
rendre Faux
lorsque la classe d'implémentation ne définit pas toutes les méthodes abstraites de l'interface. Pour ce faire, vous allez créer une métaclasse appelée ParserMeta
. Vous allez remplacer deux méthodes de dunder:
__instancecheck__
__sousclasscheck__
Dans le bloc de code ci-dessous, vous créez une classe appelée UpdatedInformalParserInterface
qui se construit à partir de la ParserMeta
métaclasse:
classe ParserMeta(type):
"" "Une métaclasse analyseur qui sera utilisée pour la création de la classe analyseur.
"" "
def __instancecheck__(cls, exemple):
revenir cls.__sousclasscheck__(type(exemple))
def __sousclasscheck__(cls, sous-classe):
revenir (hasattr(sous-classe, 'load_data_source') et
appelable(sous-classe.load_data_source) et
hasattr(sous-classe, 'extract_text') et
appelable(sous-classe.extract_text))
classe UpdatedInformalParserInterface(métaclasse=ParserMeta):
"" "Cette interface est utilisée pour les classes concrètes dont il faut hériter.
Il n'est pas nécessaire de définir les méthodes ParserMeta comme n'importe quelle classe
car ils sont implicitement mis à disposition via __subclasscheck__.
"" "
passer
Maintenant que ParserMeta
et UpdatedInformalParserInterface
ont été créés, vous pouvez créer vos implémentations concrètes.
Tout d'abord, créez une nouvelle classe d'analyse des fichiers PDF appelée PdfParserNew
:
classe PdfParserNew:
"" "Extraire le texte d'un PDF." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text(soi, full_file_path: str) -> dicter:
"" "Remplace InformalParserInterface.extract_text" ""
passer
Ici, PdfParserNew
remplace .load_data_source ()
et .extract_text ()
, donc issubclass (PdfParserNew, UpdatedInformalParserInterface)
devrait revenir Vrai
.
Dans ce bloc de code suivant, vous avez une nouvelle implémentation de l'analyseur de messagerie appelé EmlParserNew
:
classe EmlParserNew:
"" "Extraire le texte d'un e-mail." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text_from_email(soi, full_file_path: str) -> dicter:
"" "Une méthode définie uniquement dans EmlParser.
Ne remplace pas InformalParserInterface.extract_text
"" "
passer
Ici, vous avez une métaclasse qui sert à créer UpdatedInformalParserInterface
. En utilisant une métaclasse, vous n'avez pas besoin de définir explicitement les sous-classes. Au lieu de cela, la sous-classe doit définir les méthodes requises. Si ce n'est pas le cas, alors issubclass (EmlParserNew, UpdatedInformalParserInterface)
renverra False.
Fonctionnement issubclass ()
sur vos classes concrètes produira ce qui suit:
issubclass(PdfParserNew, UpdatedInformalParserInterface) # Vrai
issubclass(EmlParserNew, UpdatedInformalParserInterface) # Faux
Comme prévu, EmlParserNew
n'est pas une sous-classe de UpdatedInformalParserInterface
puisque .extract_text ()
n’était pas défini dans EmlParserNew
.
Voyons maintenant le MRO:
PdfParserNew.__mro__ # (, )
Comme vous pouvez le voir, UpdatedInformalParserInterface
est une superclasse de PdfParserNew
, mais il n'apparaît pas dans le MRO. Ce comportement inhabituel est dû au fait que UpdatedInformalParserInterface
est un classe de base virtuelle de PdfParserNew
.
Utilisation de classes de base virtuelles
Dans l'exemple précédent, issubclass (EmlParserNew, UpdatedInformalParserInterface)
retourné True, même si UpdatedInformalParserInterface
n'apparaissait pas dans le EmlParserNew
MRO. C'est parce que UpdatedInformalParserInterface
est un classe de base virtuelle de EmlParserNew
.
La principale différence entre ces sous-classes et les sous-classes standard est que les classes de base virtuelles utilisent le __sousclasscheck__
méthode dunder pour vérifier implicitement si une classe est une sous-classe virtuelle de la superclasse. De plus, les classes de base virtuelles n'apparaissent pas dans la sous-classe MRO.
Jetez un oeil à ce bloc de code:
classe PersonMeta(type):
"" "Une métaclasse de personne" ""
def __instancecheck__(cls, exemple):
revenir cls.__sousclasscheck__(type(exemple))
def __sousclasscheck__(cls, sous-classe):
revenir (hasattr(sous-classe, 'Nom') et
appelable(sous-classe.Nom) et
hasattr(sous-classe, 'âge') et
appelable(sous-classe.âge))
classe PersonSuper:
"" "Une superclasse" ""
def get_name(soi) -> str:
passer
def get_age(soi) -> int:
passer
classe La personne(métaclasse=PersonMeta):
"" "Interface Personne construite à partir de la métaclasse PersonMeta." ""
passer
Ici, vous avez la configuration pour créer vos classes de base virtuelles:
- La métaclasse
PersonMeta
- La classe de base
PersonSuper
- L'interface Python
La personne
Maintenant que la configuration pour créer classes de base virtuelles vous avez défini deux classes concrètes, Employé
et Un ami
. le Employé
hérite de la classe PersonSuper
, tandis que Un ami
hérite implicitement de La personne
:
# Hériter de sous-classes
classe Employé(PersonSuper):
"" "Hérite de PersonSuper
PersonSuper apparaîtra dans Employee .__ mro__
"" "
passer
classe Un ami:
"" "Construit implicitement à partir de Person
Friend est une sous-classe virtuelle de Person depuis
les deux méthodes requises existent.
Personne hors ami .__ mro__
"" "
def Nom(soi):
passer
def âge(soi):
passer
Bien que Un ami
n'hérite pas explicitement de La personne
, il implémente .Nom()
et .âge()
, donc La personne
devient un classe de base virtuelle de Un ami
. Quand tu cours issubclass (ami, personne)
il devrait revenir Vrai
, qui veut dire Un ami
est une sous-classe de La personne
.
Le suivant UML le diagramme montre ce qui se passe lorsque vous appelez issubclass ()
sur le Un ami
classe:
Jetez un oeil à PersonMeta
, vous remarquerez qu'il existe une autre méthode de dunder appelée __instancecheck__
. Cette méthode est utilisée pour vérifier si des instances de Un ami
sont créés à partir du La personne
interface. Votre code appellera __instancecheck__
quand vous utilisez isinstance (ami, personne)
.
Interfaces formelles
Les interfaces informelles peuvent être utiles pour les projets avec une petite base de code et un nombre limité de programmeurs. Cependant, les interfaces informelles ne seraient pas la bonne approche pour les applications plus importantes. Afin de créer un interface formelle Python, vous aurez besoin de quelques autres outils de Python abc
module.
En utilisant abc.ABCMeta
Pour appliquer l'instanciation de sous-classe des méthodes abstraites, vous utiliserez la fonction intégrée de Python ABCMeta
du abc
module. Revenons à votre UpdatedInformalParserInterface
interface, vous avez créé votre propre métaclasse, ParserMeta
, avec les méthodes de dunder surchargées __instancecheck__
et __sousclasscheck__
.
Plutôt que de créer votre propre métaclasse, vous utiliserez abc.ABCMeta
comme métaclasse. Ensuite, vous écraserez sous-classe
au lieu de __instancecheck_
et __sousclasscheck__
, car il crée une mise en œuvre plus fiable de ces méthodes de dunder.
En utilisant __sous-classehook__
Voici l'implémentation de FormalParserInterface
en utilisant abc.ABCMeta
comme métaclasse:
importation abc
classe FormalParserInterface(métaclasse=abc.ABCMeta):
@classmethod
def __sous-classehook__(cls, sous-classe):
revenir (hasattr(sous-classe, 'load_data_source') et
appelable(sous-classe.load_data_source) et
hasattr(sous-classe, 'extract_text') et
appelable(sous-classe.extract_text))
classe PdfParserNew:
"" "Extraire le texte d'un PDF." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text(soi, full_file_path: str) -> dicter:
"" "Remplace InformalParserInterface.extract_text" ""
passer
classe EmlParserNew:
"" "Extraire le texte d'un e-mail." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text_from_email(soi, full_file_path: str) -> dicter:
"" "Une méthode définie uniquement dans EmlParser.
Ne remplace pas InformalParserInterface.extract_text
"" "
passer
Si vous courez issubclass ()
sur PdfParserNew
et EmlParserNew
, puis issubclass
reviendra Vrai
et Faux
, respectivement.
En utilisant abc
enregistrer une sous-classe virtuelle
Une fois que vous avez importé le abc
module, vous pouvez directement enregistrer une sous-classe virtuelle en utilisant le .S'inscrire()
métaméthode. Dans l'exemple suivant, vous enregistrez l'interface Double
en tant que classe de base virtuelle du intégré __flotte__
classe:
classe Double(métaclasse=abc.ABCMeta):
"" "Nombre à virgule flottante double précision." ""
passer
Double.S'inscrire(flotte)
impression(issubclass(flotte, Double)) # Vrai
impression(isinstance(1,2345, Double)) # Vrai
En utilisant le .S'inscrire()
méta méthode, vous vous êtes enregistré avec succès Double
comme une sous-classe virtuelle de flotte
.
Une fois inscrit Double
, vous pouvez l'utiliser comme décorateur de classe pour définir la classe décorée comme une sous-classe virtuelle:
@Double.S'inscrire
classe Double64:
"" "Un nombre à virgule flottante double précision 64 bits." ""
passer
impression(issubclass(Double64, Double)) # Vrai
La méthode de registre du décorateur vous aide à créer une hiérarchie d'héritage de classe virtuelle personnalisée.
Utilisation de la détection de sous-classe avec enregistrement
Vous devez être prudent lorsque vous combinez __sous-classehook__
avec .S'inscrire()
, comme __sous-classehook__
a priorité sur l'enregistrement de sous-classe virtuelle. Pour vous assurer que les sous-classes virtuelles enregistrées sont prises en compte, vous devez ajouter Pas mis en œuvre
à la __sous-classehook__
méthode de dunder. le FormalParserInterface
serait mis à jour comme suit:
classe FormalParserInterface(métaclasse=abc.ABCMeta):
@classmethod
def __sous-classehook__(cls, sous-classe):
revenir (hasattr(sous-classe, 'load_data_source') et
appelable(sous-classe.load_data_source) et
hasattr(sous-classe, 'extract_text') et
appelable(sous-classe.extract_text) ou
Pas mis en œuvre)
classe PdfParserNew:
"" "Extraire le texte d'un PDF." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text(soi, full_file_path: str) -> dicter:
"" "Remplace InformalParserInterface.extract_text" ""
passer
@FormalParserInterface.S'inscrire
classe EmlParserNew:
"" "Extraire le texte d'un e-mail." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text_from_email(soi, full_file_path: str) -> dicter:
"" "Une méthode définie uniquement dans EmlParser.
Ne remplace pas InformalParserInterface.extract_text
"" "
passer
impression(issubclass(PdfParserNew, FormalParserInterface)) # Vrai
impression(issubclass(EmlParserNew, FormalParserInterface)) # Vrai
Puisque vous avez utilisé l'enregistrement, vous pouvez voir que EmlParserNew
est considéré comme une sous-classe virtuelle de votre FormalParserInterface
interface. Ce n'est pas ce que tu voulais depuis EmlParserNew
ne remplace pas .extract_text ()
. Veuillez faire preuve de prudence lors de l'enregistrement d'une sous-classe virtuelle!
Utilisation de la déclaration de méthode abstraite
Un méthode abstraite est une méthode déclarée par l'interface Python, mais elle peut ne pas avoir d'implémentation utile. La méthode abstraite doit être remplacée par la classe concrète qui implémente l'interface en question.
Pour créer des méthodes abstraites en Python, vous ajoutez le @ abc.abstractmethod
décorateur aux méthodes de l'interface. Dans l'exemple suivant, vous mettez à jour le FormalParserInterface
d'inclure les méthodes abstraites .load_data_source ()
et .extract_text ()
:
classe FormalParserInterface(métaclasse=abc.ABCMeta):
@classmethod
def __sous-classehook__(cls, sous-classe):
revenir (hasattr(sous-classe, 'load_data_source') et
appelable(sous-classe.load_data_source) et
hasattr(sous-classe, 'extract_text') et
appelable(sous-classe.extract_text) ou
Pas mis en œuvre)
@abc.méthode abstraite
def load_data_source(soi, chemin: str, nom de fichier: str):
"" "Charger dans l'ensemble de données" ""
élever NotImplementedError
@abc.méthode abstraite
def extract_text(soi, full_file_path: str):
"" "Extraire le texte de l'ensemble de données" ""
élever NotImplementedError
classe PdfParserNew(FormalParserInterface):
"" "Extraire le texte d'un PDF." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text(soi, full_file_path: str) -> dicter:
"" "Remplace InformalParserInterface.extract_text" ""
passer
classe EmlParserNew(FormalParserInterface):
"" "Extraire le texte d'un e-mail." ""
def load_data_source(soi, chemin: str, nom de fichier: str) -> str:
"" "remplace InformalParserInterface.load_data_source" ""
passer
def extract_text_from_email(soi, full_file_path: str) -> dicter:
"" "Une méthode définie uniquement dans EmlParser.
Ne remplace pas InformalParserInterface.extract_text
"" "
passer
pdf_parser = PdfParserNew() # Ne provoquera aucune erreur
eml_parser = EmlParserNew() # Générera une erreur
Dans l'exemple ci-dessus, vous avez finalement créé une interface formelle qui génère des erreurs lorsque les méthodes abstraites ne sont pas remplacées. le PdfParserNew
exemple, pdf_parser
, ne générera aucune erreur, car PdfParserNew
remplace correctement le FormalParserInterface
méthodes abstraites. cependant, EmlParserNew
générera l'erreur suivante:
Traceback (plus récent appel dernier):
Fichier "real_python_interfaces.py", ligne 53, dans <module>
eml_interface = EmlParserNew()
Erreur-type: Pouvez'instanciez pas la classe abstraite EmlParserNew avec les méthodes abstraites extract_text
Comme vous pouvez le voir, le message de trace vous indique que vous n'avez pas remplacé toutes les méthodes abstraites. C'est le comportement que vous attendez lors de la construction d'une interface Python formelle.
Interfaces dans d'autres langues
Les interfaces apparaissent dans de nombreux langages de programmation et leur implémentation varie considérablement d'un langage à l'autre. Dans les sections suivantes, vous comparerez des interfaces en Python à Java, C ++ et Go.
Java
Contrairement à Python, Java contient un interface
mot-clé. En gardant l'exemple de l'analyseur de fichiers, vous déclarez une interface en Java comme ceci:
Publique interface FileParserInterface
// Les champs statiques et les méthodes abstraites vont ici ...
Vous allez maintenant créer deux classes concrètes, PdfParser
et EmlParser
, pour mettre en œuvre FileParserInterface
. Pour ce faire, vous devez utiliser le met en oeuvre
mot-clé dans la définition de classe, comme ceci:
Publique classe EmlParser met en oeuvre FileParserInterface
Publique néant loadDataSource()
// Code pour charger l'ensemble de données
Publique néant extractText()
// Code pour extraire le texte
En poursuivant avec votre exemple d'analyse de fichiers, une interface Java entièrement fonctionnelle ressemblerait à ceci:
importation java.util. *;
importation java.io. *;
Publique classe FileParser
Publique statique néant principale(Chaîne[] args) jette IOException
Système.en dehors.println("Bonjour le monde!");
Publique interface FileParserInterface
HashMap<Chaîne, Liste des tableaux<Chaîne>> file_contents = nul;
Publique néant loadDataSource();
Publique néant extractText();
Publique classe PdfParser met en oeuvre FileParserInterface
Publique néant loadDataSource()
// Code pour charger l'ensemble de données
Publique néant extractText()
// Code pour extraire le texte
Publique classe EmlParser met en oeuvre FileParserInterface
Publique néant loadDataSource()
// Code pour charger l'ensemble de données
Publique néant extractText()
// Code pour extraire le texte
Comme vous pouvez le voir, une interface Python vous offre beaucoup plus de flexibilité lors de la création qu'une interface Java.
C ++
Comme Python, C ++ utilise des classes de base abstraites pour créer des interfaces. Lors de la définition d'une interface en C ++, vous utilisez le mot clé virtuel
pour décrire une méthode qui devrait être écrasée dans la classe concrète:
classe FileParserInterface
Publique:
virtuel néant loadDataSource(std::chaîne chemin, std::chaîne nom de fichier);
virtuel néant extractText(std::chaîne nom_fichier complet);
;
Lorsque vous souhaitez implémenter l'interface, vous donnez le nom de classe concret, suivi de deux points (:)
, puis le nom de l'interface. L'exemple suivant illustre l'implémentation de l'interface C ++:
classe PdfParser : FileParserInterface
Publique:
néant loadDataSource(std::chaîne chemin, std::chaîne nom de fichier);
néant extractText(std::chaîne nom_fichier complet);
;
classe EmlParser : FileParserInterface
Publique:
néant loadDataSource(std::chaîne chemin, std::chaîne nom de fichier);
néant extractText(std::chaîne nom_fichier complet);
;
Une interface Python et une interface C ++ présentent certaines similitudes en ce qu'elles utilisent toutes deux des classes de base abstraites pour simuler des interfaces.
Aller
Bien que la syntaxe de Go rappelle Python, le langage de programmation Go contient un interface
mot-clé, comme Java. Créons le fileParserInterface
dans Go:
type fileParserInterface interface
loadDataSet(chemin chaîne, nom de fichier chaîne)
extractText(full_file_path chaîne)
Une grande différence entre Python et Go est que Go n'a pas de classes. Au contraire, Go est similaire à C en ce qu'il utilise le struct
mot-clé pour créer des structures. UNE structure est similaire à une classe dans la mesure où une structure contient des données et des méthodes. Cependant, contrairement à une classe, toutes les données et méthodes sont accessibles au public. Les structures concrètes de Go seront utilisées pour mettre en œuvre fileParserInterface
.
Voici un exemple de la façon dont Go utilise les interfaces:
paquet principale
importation (
"fmt"
)
type fileParserInterface interface
loadDataSet(chemin chaîne, nom de fichier chaîne)
extractText(full_file_path chaîne)
type pdfParser struct
// Les données vont ici ...
type emlParser struct
// Les données vont ici ...
func (p pdfParser) loadDataSet()
// Définition de la méthode ...
func (p pdfParser) extractText()
// Définition de la méthode ...
func (e emlParser) loadDataSet()
// Définition de la méthode ...
func (e emlParser) extractText()
// Définition de la méthode ...
func principale()
fmt.Printf("Bonjour le monde!")
Contrairement à une interface Python, une interface Go est créée à l'aide de structures et du mot clé explicite interface
.
Conclusion
Python offre une grande flexibilité lorsque vous créez des interfaces. Une interface Python informelle est utile pour les petits projets où vous êtes moins susceptible de vous tromper quant aux types de retour des méthodes. À mesure qu’un projet se développe, la nécessité interface formelle Python devient plus important car il devient plus difficile de déduire les types de retour. Cela garantit que la classe concrète, qui implémente l'interface, écrase les méthodes abstraites.
Maintenant vous pouvez:
- Comprendre comment fonctionnent les interfaces et les mises en garde de la création d'une interface Python
- Comprendre le utilité des interfaces dans un langage dynamique comme Python
- Mettre en place formel et informel interfaces en Python
- Comparer les interfaces Python à ceux des langages comme Java, C ++ et Go
Maintenant que vous vous êtes familiarisé avec la façon de créer une interface Python, ajoutez une interface Python à votre prochain projet pour voir son utilité en action!
[ad_2]