49 votes

Quelle est la version Python pour «Code contre une interface, pas un objet»?

Inspiré par une grande question (et des tas de réponses grands) à partir d' ici.

L'énoncé "le Code par rapport à l'interface, ce n'est pas un objet" ont aucune signification en Python?

Je suis à la recherche de réponses comme celles de la Question d'Origine mais avec Python fragments et pensées.

65voto

kindall Points 60645

"Le Code par rapport à l'interface, ce n'est pas un objet" ne fait pas sens littéral en Python, parce que la langue ne dispose pas d'une fonctionnalité de l'interface. Le rugueux Python équivalent est "l'utilisation du duck-typing." Si vous voulez voir si un objet est un canard, en d'autres termes, vous devriez vérifier pour voir si elle a un quack() méthode, ou mieux encore, essayez d' quack() et d'assurer une gestion d'erreur, pas de test pour voir si c'est une instance d' Duck.

Commune de canard types de Python sont des fichiers (bien, vraiment, de fichiers objets), les mappages (dict-comme des objets), callables (fonction-comme des objets), et des séquences (list-comme des objets).

Comme un exemple, Python caractéristiques qui le souhaitent, un fichier sera généralement heureux d'accepter un objet qui implémente les méthodes de file il a besoin; il ne doit pas être dérivée à partir de l' file classe. Pour utiliser un objet comme standard, par exemple, la chose principale, il va avoir besoin est un write() (et peut-être flush() et close(), ce qui n'a pas besoin de faire quoi que ce soit). De même, un callable est un objet qui a un __call__() méthode; il ne doit pas être dérivée de la fonction type (en fait, vous ne pouvez pas tirer du type de fonction).

Vous devez prendre une approche similaire. Vérifier les méthodes et les attributs dont vous avez besoin pour ce que vous allez faire avec un objet. Mieux encore, le document que vous en attendez et à supposer que celui qui appelle votre code n'est pas un total doofus. (Si on vous donne un objet que vous ne pouvez pas utiliser, ils vont certainement le faire assez rapidement les erreurs qu'ils ont.) Test pour des types spécifiques uniquement lorsque c'est nécessaire. Il est nécessaire à certains moments, c'est pourquoi Python vous donne type(), isinstance(), et issubclass(), mais être prudent avec eux.

Python duck-typing est l'équivalent d'un "code à l'encontre d'une interface, pas un objet", dans le sens que vous êtes conseillé de ne pas mettre votre code trop dépendante sur un type de l'objet, mais plutôt de voir si elle a de l'interface dont vous avez besoin. La différence est que dans Python, "interface" signifie simplement informelle-un ensemble de méthodes et attributs d'un objet qui fournissent un certain comportement, plutôt que d'une construction du langage spécifiquement nommées interface.

Vous pouvez formaliser Python "interfaces" dans une certaine mesure, à l'aide de l' abc module, qui permet de déclarer qu'une classe est une sous-classe d'une "classe de base abstraite" (interface) à l'aide de l'un quelconque des critères que vous voulez, comme "il a des attributs color, tail_length, et quack, et quack est appelable." Mais c'est encore beaucoup moins strictes que les langages statiques ayant une fonction d'interface.

30voto

Paulo Scardine Points 17518

Pour comprendre les interfaces en Python, vous devez comprendre duck-typing. Dès le Python glossaire:

duck-typing: Un style de programmation qui ne ressemble pas à un type de l'objet pour déterminer s'il a le droit de l'interface; au lieu de cela, la méthode ou d'un attribut est simplement appelé ou utilisé ("Si ça ressemble à un canard et les charlatans comme un canard, il doit etre un canard.") En mettant l'accent sur les interfaces plutôt que des types spécifiques, bien conçus code améliore sa souplesse en permettant polymorphe de substitution. Duck-typing évite de tests à l'aide de type() ou isinstance(). (Notez, cependant, que le canard-typage peut être complétée avec les classes de base abstraites.) Au lieu de cela, il utilise habituellement des hasattr() de l'examen ou de l'aeap de programmation.

Python encourage de codage pour les interfaces, seulement elles ne sont pas appliquées, mais par convention. Des Concepts comme iterables, callables ou le fichier de l'interface sont très envahissant en Python ainsi que les objets internes qui s'appuient sur les interfaces de la carte, le filtre ou le réduire.

19voto

Ninefingers Points 18767

Une interface vous attendre à ce que certaines méthodes pour être présent et standardisé dans tous les objets; c'est le point d'une interface ou une classe de base abstraite, ou quel que soit mise en œuvre que vous envisagez.

Par exemple (Java), on peut avoir une interface pour le chiffrement symétrique comme suit:

public interface cipher 
{
    public void encrypt(byte[] block, byte[] key); 
    public void decrypt(byte[] block, byte[] key);    
}

Ensuite, vous pouvez la mettre en œuvre:

public class aes128 implements cipher
{ 
    public void encrypt(byte[] block, byte[] key)
    {
        //...
    }
    public void decrypt(byte[] block, byte[] key)
    {
        //...
    }
}

Il est alors possible de déclarer un objet de la sorte:

cipher c;

Qu'avons-nous fait ici? Eh bien, nous avons créé cet objet c dont le type doit correspondre à celle de l'interface. c pouvez faire référence à quelque chose qui correspond à cette interface, de sorte que, à l'étape suivante:

c = new aes128();

Vous pouvez maintenant appeler les méthodes que vous attendez d'un cipher à avoir.

C'est de java. Maintenant, voici ce que vous devez faire en python:

class aes128(Object):

    def __init__(self):
        pass

    def encrypt(self, block, key):
        # here I am going to pass, but you really 
        # should check what you were passed, it could be 
        # anything. Don't forget, if you're a frog not a duck
        # not to quack!
        pass

Lorsque vous souhaitez utiliser, et vous n'êtes pas sûr que l'objet que vous avez été transmis, juste essayer de l'utiliser:

c = aes128()
try:
    c.encrypt(someinput, someoutput)
except:
    print "eh? No encryption method?!"

Ici, vous êtes en s'appuyant sur c.chiffrer la mise en œuvre d' raise si il ne peut pas gérer ce qu'il a été adopté, si la méthode existe. Bien sûr, si c est un type de chaîne et n'est donc pas le type dont vous avez besoin, il va également lancer automatiquement, et vous attraperez (espérons-le).

En bref, une forme de programmation est tapé tel que vous avez à obéir à l'interface des règles, l'autre est en train de dire que vous n'avez même pas besoin de les écrire, il vous suffit de faire confiance que si il n'a pas d'erreur, il a travaillé.

J'espère que vous montre la pratique, la différence entre les deux.

0voto

Jörg W Mittag Points 153275

Quelle est la version de Python pour "Code à l'encontre d'une interface, pas un objet."?

La bonne citation est "programme à l'encontre d'une interface, pas pour une mise en œuvre". Le principe s'applique de la même manière en Python qu'il a fait en Smalltalk, la langue dans laquelle il est originaire.

L'énoncé "le Code par rapport à une interface, pas un objet." ont aucune signification en Python?

Oui. Il a la même signification en Python qu'il a dans la langue que cette citation provient de (Smalltalk), et dans toute autre langue.

Prograide.com

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.

Powered by:

X