0Pricing
Python Academy · Leçon

TypeVar, classes génériques et Protocol

Définissez des types génériques réutilisables et un sous-typage structurel avec Protocol.

TypeVar, classes génériques et Protocol est une leçon Python Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Python Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Python Academy comprend 4 leçons au total.

Qu'est-ce que TypeVar ?

TypeVar déclare une variable de type, c'est-à-dire un emplacement pouvant contenir n'importe quel type, avec des restrictions si nécessaire. Il est utilisé dans les fonctions et les classes génériques.

from typing import TypeVar

T = TypeVar("T")

def identity(value: T) -> T:
    return value

print(identity(42))      # int
print(identity("hello")) # str

Fonctions génériques

Une fonction qui utilise TypeVar à la fois pour les types de ses paramètres et pour son type de retour permet à mypy d'inférer le type de retour à partir du type de l'argument.

from typing import TypeVar

T = TypeVar("T")

def first(items: list[T]) -> T:
    return items[0]

x: int = first([1, 2, 3])     # mypy knows x is int
s: str = first(["a","b","c"]) # mypy knows s is str

TypeVar contraint

Transmettez des contraintes de type à TypeVar pour limiter les types acceptés.

from typing import TypeVar

Numeric = TypeVar("Numeric", int, float)

def double(n: Numeric) -> Numeric:
    return n * 2

print(double(5))    # 10
print(double(2.5))  # 5.0
# double("x")  # mypy error

Classes génériques

Héritez de Generic[T] pour créer une classe paramétrée par une variable de type.

from typing import Generic, TypeVar

T = TypeVar("T")

class Stack(Generic[T]):
    def __init__(self) -> None:
        self._items: list[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

stack: Stack[int] = Stack()
stack.push(1)
print(stack.pop())   # 1

Plusieurs TypeVars

Utilisez plusieurs TypeVars pour paramétrer une classe ou une fonction avec deux types indépendants.

from typing import Generic, TypeVar

K = TypeVar("K")
V = TypeVar("V")

class Pair(Generic[K, V]):
    def __init__(self, key: K, value: V) -> None:
        self.key = key
        self.value = value

p: Pair[str, int] = Pair("age", 30)
print(p.key, p.value)   # age 30

Protocol — Sous-typage structurel

Protocol définit une interface à partir des méthodes et attributs qu'une classe doit posséder, sans exiger d'héritage explicite (« typage canard, vérifié par le système de types »).

from typing import Protocol

class Drawable(Protocol):
    def draw(self) -> None: ...

def render(obj: Drawable) -> None:
    obj.draw()

class Circle:
    def draw(self) -> None:
        print("Drawing circle")

render(Circle())   # works — Circle satisfies Drawable

Protocol avec runtime_checkable

Ajoutez @runtime_checkable à un Protocol pour activer les vérifications isinstance() à l'exécution.

from typing import Protocol, runtime_checkable

@runtime_checkable
class Closeable(Protocol):
    def close(self) -> None: ...

class File:
    def close(self) -> None: print("closed")

print(isinstance(File(), Closeable))   # True

Protocol ou ABC

Les ABC exigent un héritage explicite (class Dog(Animal)). Les Protocol fonctionnent par correspondance structurelle : si une classe possède les bonnes méthodes, elle respecte le protocole, quelle que soit sa relation d'héritage.

from typing import Protocol
from abc import ABC, abstractmethod

# ABC: nominal typing
class Printable(ABC):
    @abstractmethod
    def display(self) -> None: ...

# Protocol: structural typing
class Displayable(Protocol):
    def display(self) -> None: ...

TypeVar avec bound

TypeVar("T", bound=BaseClass) limite T à BaseClass ou à l'une de ses sous-classes.

from typing import TypeVar

class Animal:
    def speak(self) -> str: return "..."

A = TypeVar("A", bound=Animal)

def make_speak(animal: A) -> str:
    return animal.speak()

Alias générique — Python 3.12

Python 3.12 introduit l'instruction type pour créer des alias de types clairs, ainsi que la syntaxe class Foo[T] pour les génériques sans importer TypeVar.

# Python 3.12+
type Vector = list[float]
type Matrix = list[Vector]

class Stack[T]:
    def __init__(self) -> None: self._items: list[T] = []
    def push(self, item: T) -> None: self._items.append(item)
    def pop(self) -> T: return self._items.pop()

Type Self

Self (depuis typing en 3.11+) annote les méthodes qui renvoient la classe actuelle, ce qui est utile dans les interfaces chaînées et les sous-classes.

from typing import Self

class Builder:
    def __init__(self) -> None:
        self.parts: list[str] = []

    def add(self, part: str) -> Self:
        self.parts.append(part)
        return self

b = Builder().add("a").add("b")
print(b.parts)   # ["a", "b"]

Vérification rapide

Quelle est la différence essentielle entre un Protocol et une ABC dans le système de types de Python ?

Récapitulatif

TypeVar crée des emplacements de type pour les fonctions et les classes génériques. Generic[T] paramètre les classes. Protocol permet le sous-typage structurel sans héritage. Utilisez bound= ou des contraintes de type sur TypeVar pour limiter les types acceptés.

Questions Fréquemment Posées

La leçon « TypeVar, classes génériques et Protocol » est-elle gratuite ?

Oui — le texte complet de « TypeVar, classes génériques et Protocol » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Python Academy, passe à CoddyKit PRO. Le cours Python Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « TypeVar, classes génériques et Protocol » ?

Définissez des types génériques réutilisables et un sous-typage structurel avec Protocol. Tu pratiques Python Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Python Academy ?

Aucune expérience préalable n'est requise. Python Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « TypeVar, classes génériques et Protocol » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Python Academy ?

Oui. Chaque leçon Python Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Annotations de types de base
  2. Types complexes : List, Dict, Optional, Union
  3. TypeVar, classes génériques et Protocol
  4. Exécuter mypy et corriger les erreurs de types
← Retour à Python Academy