Maison >développement back-end >Tutoriel Python >Une introduction détaillée au typage de canard de Python
Je pense que les développeurs Python connaissent le typage canard de Python. La définition précise du typage canard dans Wikipédia est « un style de typage dynamique ». Dans ce style, la sémantique effective d'un objet n'est pas déterminée par l'héritage d'une classe spécifique ou l'implémentation d'une interface spécifique, mais par « l'ensemble actuel de méthodes et de propriétés ». Cet article vous donne donc le typage canard de Python.
Définition de base du type canard
Tout d'abord, Python ne prend pas en charge le polymorphisme, ni n'a besoin de prendre en charge le polymorphisme. Python est une sorte de polymorphisme, prônant le typage canard.
Ce qui suit est une discussion sur le typage de canard sur Wikipédia :
En programmation, le typage de canard (anglais : typage de canard) est un style de typage dynamique. Dans ce style, la sémantique effective d'un objet est déterminée non pas par l'héritage d'une classe spécifique ou par l'implémentation d'une interface spécifique, mais par l'ensemble actuel de méthodes et de propriétés. Le nom de ce concept vient du test du canard proposé par James Whitcomb Riley. Le "test du canard" peut s'exprimer ainsi :
"Quand vous voyez un oiseau qui marche comme un canard, nage comme un canard. un canard, et cancane comme un canard, S'il ressemble à un canard, l'oiseau peut être appelé un canard. Dans la frappe du canard, l'accent n'est pas mis sur le type de l'objet lui-même, mais sur la façon dont il est utilisé. Par exemple, dans un langage qui n'utilise pas le typage duck, nous pourrions écrire une fonction qui prend un objet de type duck et appelle ses méthodes walk et bark. Dans un langage qui utilise le typage duck, une telle fonction peut accepter un objet de n'importe quel type et appeler ses méthodes walk et call. Si les méthodes qui doivent être appelées n’existent pas, une erreur d’exécution sera générée. Le fait que tout objet avec les méthodes de marche et d'appel correctes puisse être accepté par une fonction conduit à l'instruction ci-dessus, d'où le nom de cette façon de déterminer les types.
Le typage Duck gagne souvent à ne pas tester les types d'arguments dans les méthodes et les fonctions, mais à s'appuyer plutôt sur la documentation, le code clair et les tests pour garantir une utilisation correcte. Les utilisateurs passant de langages à typage statique à des langages à typage dynamique tentent souvent d'ajouter une vérification de type statique (avant l'exécution), compromettant ainsi les avantages et l'évolutivité du typage canard et limitant la nature dynamique du langage.
Le code suivant est un type de canard simple
class duck(): def walk(self): print('I walk like a duck') def swim(self): print('i swim like a duck') class person(): def walk(self): print('this one walk like a duck') def swim(self): print('this man swim like a duck')Pour un type canard, nous ne nous soucions pas du type de l'objet lui-même ou de l'héritage de classe, mais de la façon dont la classe est utilisée. Nous pouvons appeler les méthodes de ces classes via le code suivant.
def watch_duck(animal): animal.walk() animal.swim() small_duck = duck() watch_duck(small_duck) output >> I walk like a duck i swim like a duck duck_like_man = person() watch_duck(duck_like_man) output >> this one walk like a duck this man swim like a duck class Lame_Foot_Duck(): def swim(self): print('i am lame but i can swim') lame_duck = Lame_Foot_Duck() watch_duck(lame_duck) output >> AttributeError: Lame_Foot_Duck instance has no attribute 'walk'
La fonction reçoit l'objet de cette classe, puis ne vérifie pas le type de l'objet, mais appelle directement la marche et fonctions de natation de cet objet Méthode, si la méthode requise n'existe pas, une erreur sera signalée.
Le mode de réalisation spécifique du typage canard en python est tel qu'indiqué dans le code suivant watch_duck
class CollectionClass(): lists = [1,2,3,4] def __getitem__(self, index): return self.lists[index] iter_able_object = CollectionClass() class Another_iterAbleClass(): lists=[1,2,3,4] list_position = -1 def __iter__(self): return self def next(self): #还有更简单的实现,使用生成器或迭代器什么的:) self.list_position += 1 if self.list_position >3: raise StopIteration return self.lists[self.list_position] another_iterable_object=Another_iterAbleClass() print(iter_able_object[1]) print(iter_able_object[1:3]) output>> 2 [2, 3] another_iterable_object[2] output>> Traceback (most recent call last): File "/Users/steinliber/a.py", line 32, in <module> another_iterable_object[2] TypeError: 'Another_iterAbleClass' object does not support indexing print(next(another_iterable_object)) output>> 1 print(next(another_iterable_object)) output>> 2 print(next(iter_able_object)) output>> Traceback (most recent call last): File "/Users/steinliber/a.py", line 29, in <module> print(next(iter_able_object)) TypeError: IterAbleClass object is not an iteratorEn python, la méthode d'implémentation du Le code ci-dessus est appelé Protocole, ces protocoles peuvent être considérés comme des interfaces de notification, qui spécifient quelles méthodes de l'objet l'appelant doit appeler pour utiliser cette fonction, et quelles méthodes l'appelé doit implémenter pour remplir cette fonction. La différence entre celle-ci et l'interface en Java est que la fonction d'interface en Java doit être implémentée par héritage. La classe héritée doit implémenter toutes les méthodes abstraites de l'interface, donc le concept de type est souligné en Java, tandis que
en Python, c'est plus La plupart d'entre eux sont informatifs.Une fonction spécifie quelles méthodes de l'objet passé doivent être appelées pour implémenter une certaine fonction.Toutes les classes qui implémentent ces méthodes peuvent implémenter cette fonction.
S'agissant spécifiquement des deux classes ci-dessus, la première classe implémente la méthode protocol
, puis l'interpréteur Python la traitera comme une collection et vous pourrez utiliser des tranches sur des objets de cette classe pour des méthodes telles que. obtenant des sous-éléments, si la deuxième classe implémente les méthodes
, Python pensera qu'il s'agit d'un itérateur, et pourra obtenir chaque sous-élément via une boucle sur l'objet de cette classe. Une classe peut implémenter les méthodes qu’elle est capable d’implémenter et ne peut être utilisée que dans les situations où cela a du sens. __getitem__
__iter__
Par rapport à la classe duck ci-dessus, le [] utilisé pour la coupe des bords (qui appelle en fait la fonction next
de python) et le
Fonctions, ces fonctions reçoivent des objets de toute classe et appelez des méthodes dans les objets requis pour implémenter la fonction pour implémenter la fonction. Si l'objet méthode appelé dans la fonction n'existe pas, une erreur sera signalée. slice
iter()
Comme le montre ce qui précède, la flexibilité du typage python duck est qu'il se concentre sur la façon dont l'objet appelé est utilisé, plutôt que sur le type d'objet lui-même. Par conséquent, il n'est pas recommandé d'utiliser watch_duck
pour déterminer le type de paramètres entrants en python. Une meilleure méthode consiste à utiliser directement les paramètres entrants et à utiliser try et
Résumé
Ce qui précède est une introduction détaillée aux types de canards Python. Le contenu de cet article est toujours très détaillé. J'espère qu'il sera utile. tout le monde apprend Python, si vous avez des questions, vous pouvez laisser un message pour communiquer.
Pour des articles plus détaillés sur le typage canard de Python, veuillez faire attention au site Web PHP chinois !