ProgrammationDéveloppeur Python

Qu'est-ce que les annotations de fonction en Python, comment fonctionne le mécanisme des type hints, influencent-elles l'exécution du code à l'exécution et quelles erreurs commettent les développeurs imprudents ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Historique de la question

Les annotations de fonction sont apparues dans Python 3.0, et le mécanisme des type hints est décrit dans le PEP 484, ajouté avec la version 3.5. Cet outil a été créé pour l'analyse statique du code, l'auto-complétion et l'amélioration de la lisibilité - la bibliothèque standard de types (typing) permet d'indiquer explicitement les types attendus des variables, des arguments et des valeurs de retour des fonctions.

Problème

Python est un langage dynamique où les types de variables peuvent changer pendant l'exécution, ce qui peut entraîner des erreurs uniquement au moment de l'exécution du programme. Les annotations n'affectent pas l'exécution du code, mais une mauvaise utilisation peut donner aux programmeurs un faux sentiment de "typage strict".

Solution

Les annotations de type sont utilisées pour la documentation, la vérification automatique avec des outils comme mypy, pylance, pyright et similaires, ainsi que pour l'intégration avec les IDE. Elles sont mises en œuvre par des deux-points après le nom de l'argument et une flèche après la liste des paramètres :**

def greet(name: str, times: int = 1) -> None: for _ in range(times): print(f"Hello, {name}!") # Annotation correcte pour une fonction de traitement de dictionnaire from typing import Dict, List def transform(data: Dict[str, List[int]]) -> float: return sum(sum(lst) for lst in data.values()) / 10

Caractéristiques clés :

  • Les annotations ne sont pas vérifiées par l'interpréteur, elles restent lors de l'exécution du code, mais ne modifient en rien l'exécution
  • Elles sont pertinentes pour les grands projets où il est important de comprendre les interfaces et l'interaction des composants
  • Pour des constructions complexes, des typing.List, typing.Dict, typing.Optional, typing.Union, etc. sont nécessaires.

Questions piégées.

Python peut-il "automatiquement" vérifier la conformité aux types déclarés dans les annotations ?

Non ! La vérification des types se fait uniquement par des outils externes d'analyse statique, comme mypy. À l'exécution, Python ignore complètement le contenu des annotations.

def f(x: int): return x * 2 print(f('oops')) # Type str, aucune erreur ne sera levée !

Où sont stockées les annotations et comment les obtenir à l'exécution, pourquoi cela pourrait-il être nécessaire ?

Elles sont stockées dans un attribut spécial annotations :

def add(x: int, y: int) -> int: return x + y print(add.__annotations__) # {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}

Cela est utilisé par des bibliothèques tierces pour la validation des données, l'auto-génération de documentation, la sérialisation, etc.

Peut-on annoter n'importe quelle variable, uniquement des fonctions, que se passe-t-il dans l'espace global ?

On peut annoter à la fois des variables locales et globales via les deux-points, cela n'affecte pas non plus l'exécution :

index: int = 0 def func(x: 'User') -> None: ...

Erreurs typiques et anti-patterns

  • Croire que les type hints font partie du typage strict et du contrôle strict des types
  • Oublier que les valeurs par défaut doivent être compatibles avec le type déclaré (bien que cela ne soit pas vérifié à l'exécution)
  • Mauvaise utilisation de types complexes de typing (par exemple, List<int> au lieu de List[int])

Exemple concret

Cas négatif

Dans un projet d'entreprise, tous les développeurs ont commencé à intégrer activement des annotations, mais les types réels des arguments des fonctions ne correspondaient souvent pas à ceux indiqués. Python laissait passer ces erreurs, et des bogues inattendus apparaissaient uniquement au cœur de la logique métier. La configuration de mypy était absente.

Avantages :

  • Amélioration de l'auto-complétion et de la documentation

Inconvénients :

  • Resté des erreurs implicites, éloignant la cause du lieu d'annotation

Cas positif

Utilisation des type hints et lancement obligatoire de mypy dans le CI, ainsi que l'auto-génération de documentation à partir des annotations :

Avantages :

  • Minimum d'erreurs dues à des incohérences de types
  • Amélioration de la qualité de la collaboration sur l'API

Inconvénients :

  • Une charge de travail supplémentaire apparaît pour maintenir l'actualité des annotations lors du refactoring