
Emmanuel Chomarat

Si vous travaillez avec les annotations de type en Python, vous avez probablement rencontré des problèmes de références circulaires ou des imports lourds qui ralentissent le démarrage de votre application. Dans cet article, nous allons explorer deux outils puissants qui résolvent ces problèmes : from __future__ import annotations et typing.TYPE_CHECKING.
Par défaut, Python évalue les annotations de type au moment de l'import du module. Cela peut créer plusieurs problèmes :
Voyons comment résoudre ces problèmes.
from __future__ import annotationsCette fonctionnalité change la manière dont Python traite les annotations de type. Au lieu de les évaluer immédiatement, Python les stocke sous forme de chaînes de caractères.
from __future__ import annotations
class Node:
def __init__(self, value: int, next: Node = None):
self.value = value
self.next = nextSans cet import, vous auriez besoin d'écrire next: 'Node' avec des guillemets.
Oui ! Même si Python 3.12 supporte nativement list[str] et dict[str, int], cet import reste utile pour :
TYPE_CHECKINGLa véritable puissance vient de la combinaison avec typing.TYPE_CHECKING. Cette constante est toujours False au runtime, mais les linters / vérificateurs de type (mypy, pyright, pyrefly, ty) la traitent comme True.
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import pandas as pd
from heavy_package import HeavyClass
from circular_module import OtherClass
def process_data(df: pd.DataFrame) -> None:
# pandas n'est PAS importé au runtime !
pass
def handle_object(obj: HeavyClass) -> None:
# HeavyClass n'est PAS importée au runtime !
pass1. Éviter les imports circulaires
# module_a.py
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from module_b import ClassB
class ClassA:
def work_with(self, other: ClassB) -> None:
pass2. Dépendances optionnelles
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import tensorflow as tf # L'utilisateur n'a peut-être pas tensorflow
def train_model(model: tf.keras.Model | None = None) -> None:
if model is not None:
import tensorflow as tf # Import seulement si utilisé
# ... utiliser tensorflow3. Optimiser les performances
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import torch
import transformers
# Bibliothèques lourdes importées uniquement pour le typage
def load_model(config: transformers.PretrainedConfig) -> None:
passLorsque vous utilisez des annotations sous forme de chaînes, Python les résout en utilisant le namespace du module où l'annotation a été définie.
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from package_a.models import User as UserA
from package_b.models import User as UserB
import package_b.models # Nécessaire pour process_b
def process_a(user: UserA) -> None:
# Résolu via l'espace de noms local
pass
def process_b(user: package_b.models.User) -> None:
# Nom complètement qualifié - toujours sans ambiguïté
passPour obtenir les types réels au runtime :
import typing
hints = typing.get_type_hints(process_a)
# Évalue "UserA" dans l'espace de noms du moduleSi vous devez utiliser le type au runtime (pour isinstance(), créer des instances, etc.), vous devez toujours l'importer normalement :
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from package_a import User
def process(user: User) -> None:
from package_a import User # Import réel nécessaire !
if isinstance(user, User):
# ... faire quelque chose
passfrom __future__ import annotations + TYPE_CHECKINGpackage.module.Classe évite les ambiguïtésisinstance() et la création d'instancesLa combinaison de from __future__ import annotations et typing.TYPE_CHECKING est un pattern de best practice en Python moderne. Elle vous permet de :
Ces outils sont particulièrement précieux dans les grandes bases de code où la gestion des dépendances et des performances d'import devient critique.
Adoptez ce pattern dès maintenant, et vos projets Python seront plus maintenables et plus performants !