Maison >développement back-end >Tutoriel Python >Duck Typing rencontre les indices de type : utilisation de protocoles en Python
La nature dynamique de Python et la prise en charge du typage canard ont longtemps été louées pour leur flexibilité. Cependant, à mesure que les bases de code deviennent plus volumineuses et plus complexes, les avantages de la vérification de type statique deviennent de plus en plus évidents. Mais comment concilier la flexibilité du typage canard et la sécurité de la vérification de type statique ? Entrez dans la classe Protocol de Python.
Dans ce tutoriel, vous apprendrez :
Le typage Duck est un concept de programmation où le type ou la classe d'un objet est moins important que les méthodes qu'il définit. C'est basé sur l'idée que "S'il ressemble à un canard, nage comme un canard et cancane comme un canard, alors c'est probablement un canard."
En Python, la saisie en canard est entièrement prise en charge. Par exemple :
class Duck: def quack(self): print("Quack!") class Person: def quack(self): print("I'm imitating a duck!") def make_it_quack(thing): # Note: No type hint here thing.quack() duck = Duck() person = Person() make_it_quack(duck) # Output: Quack! make_it_quack(person) # Output: I'm imitating a duck!
Dans cet exemple, make_it_quack ne se soucie pas du type de chose. Il s'en soucie seulement que cette chose ait une méthode de charlatan. Notez qu'il n'y a pas d'indice de type pour le paramètre thing, ce qui est typique dans le code typé canard mais peut entraîner des problèmes dans des bases de code plus volumineuses.
Le typage canard offre plusieurs avantages :
Cependant, il présente également quelques inconvénients :
Une approche pour résoudre ces problèmes consiste à utiliser des classes de base abstraites (ABC). Voici un exemple :
from abc import ABC, abstractmethod class Quacker(ABC): @abstractmethod def quack(self): pass class Duck(Quacker): def quack(self): print("Quack!") class Person(Quacker): def quack(self): print("I'm imitating a duck!") def make_it_quack(thing: Quacker): thing.quack() duck = Duck() person = Person() make_it_quack(duck) make_it_quack(person)
Bien que cette approche fournisse une meilleure vérification de type et des interfaces plus claires, elle présente des inconvénients :
Python 3.8 a introduit la classe Protocol, qui nous permet de définir des interfaces sans nécessiter d'héritage. Voici comment nous pouvons l'utiliser :
from typing import Protocol class Quacker(Protocol): def quack(self):... class Duck: def quack(self): print("Quack!") class Person: def quack(self): print("I'm imitating a duck!") def make_it_quack(thing: Quacker): thing.quack() duck = Duck() person = Person() make_it_quack(duck) make_it_quack(person)
Décomposons cela :
Cette approche nous apporte plusieurs avantages :
Voici un exemple plus complexe montrant comment les protocoles peuvent être aussi complexes que nécessaire (forme), en gardant vos classes de domaine (cercle, rectangle) plates :
from typing import Protocol, List class Drawable(Protocol): def draw(self): ... class Resizable(Protocol): def resize(self, factor: float): ... class Shape(Drawable, Resizable, Protocol): pass def process_shapes(shapes: List[Shape]): for shape in shapes: shape.draw() shape.resize(2.0) # Example usage class Circle: def draw(self): print("Drawing a circle") def resize(self, factor: float): print(f"Resizing circle by factor {factor}") class Rectangle: def draw(self): print("Drawing a rectangle") def resize(self, factor: float): print(f"Resizing rectangle by factor {factor}") # This works with any class that has draw and resize methods, # regardless of its actual type or inheritance shapes: List[Shape] = [Circle(), Rectangle()] process_shapes(shapes)
Dans cet exemple, Circle et Rectangle n'héritent pas de Shape ou de toute autre classe. Ils implémentent simplement les méthodes requises (dessiner et redimensionner). La fonction process_shapes peut fonctionner avec tous les objets dotés de ces méthodes, grâce au protocole Shape.
Les protocoles en Python fournissent un moyen puissant d'apporter le typage statique au code typé canard. Ils nous permettent de spécifier des interfaces dans le système de types sans nécessiter d'héritage, en conservant la flexibilité du typage duck tout en ajoutant les avantages de la vérification de type statique,
En utilisant les protocoles, vous pouvez :
Si vous souhaitez en savoir plus sur les protocoles et les indications de type en Python, consultez la documentation officielle de Python sur le module de saisie ou explorez les outils avancés de vérification de type statique comme mypy.
Bon codage, et que vos canards cancanent toujours avec la sécurité des types !
Vous pouvez trouver plus de mon contenu, y compris ma newsletter ici
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!