Python Type Hints : code plus sûr et plus clair
Vous avez probablement déjà rencontré une fonction Python qui renvoie différents types selon l'entrée, ou une variable qui change de type en cours de route. Ces ambiguïtés entraînent des erreurs d'exécution qui auraient pu être détectées plus tôt. Les type hints Python résolvent ce problème en vous permettant d'annoter les types attendus, rendant votre code auto-documenté et permettant aux outils d'analyse statique de détecter les erreurs avant l'exécution.
Dans cet article, nous allons explorer comment utiliser efficacement les type hints en Python, des annotations de base aux patterns avancés, et comment ils contribuent à un code plus sûr et plus clair.
Que sont les type hints Python ?
Les type hints (aussi appelés annotations de type) sont une syntaxe introduite dans Python 3.5 (PEP 484) qui vous permet de spécifier les types attendus des variables, des paramètres de fonction et des valeurs de retour. Ils ne sont pas appliqués à l'exécution mais sont utilisés par les vérificateurs de types statiques comme mypy, pyright et les IDE pour détecter les erreurs liées aux types.
Par exemple :
def greet(name: str) -> str:
return f"Hello, {name}"
Ici, name: str indique que name doit être une chaîne de caractères, et -> str indique que la fonction renvoie une chaîne de caractères.
Pourquoi utiliser les type hints ?
- Détection précoce des bugs : Les vérificateurs de types statiques peuvent détecter les incompatibilités de types avant l'exécution du code.
- Lisibilité améliorée : Les type hints servent de documentation en ligne, facilitant la compréhension du code par les autres (et par vous-même plus tard).
- Meilleur support IDE : L'autocomplétion, le refactoring et la navigation deviennent plus précis.
- Maintenabilité renforcée : Lors du refactoring, les type hints aident à garantir que vous ne cassez pas les contrats.
- Facilite la collaboration : Les équipes peuvent communiquer clairement les interfaces attendues.
Annotations de type de base
Vous pouvez annoter les variables, les paramètres de fonction et les types de retour.
Variables
age: int = 30
name: str = "Alice"
Fonctions
def add(a: int, b: int) -> int:
return a + b
Collections
Pour les listes, dictionnaires, etc., utilisez le module typing (ou les génériques natifs dans Python 3.9+) :
from typing import List, Dict
def process(items: List[str]) -> Dict[str, int]:
return {item: len(item) for item in items}
Dans Python 3.9+, vous pouvez utiliser list[str] et dict[str, int] directement.
Type hints avancés
À mesure que votre code grandit, vous rencontrerez des scénarios plus complexes. Voici quelques fonctionnalités avancées.
Optional et Union
Optional[T] est un raccourci pour Union[T, None], indiquant une valeur qui peut être de type T ou None.
from typing import Optional
def find_user(user_id: int) -> Optional[str]:
# returns username or None if not found
...
Dans Python 3.10+, vous pouvez utiliser l'opérateur | : str | None.
Callable
Pour les fonctions en tant qu'arguments :
from typing import Callable
def apply_func(func: Callable[[int], int], value: int) -> int:
return func(value)
Génériques
Créez des composants réutilisables avec des variables de type :
from typing import TypeVar, List
T = TypeVar('T')
def first(items: List[T]) -> T:
return items[0]
TypedDict
Pour les dictionnaires avec un ensemble fixe de clés et de types de valeurs :
from typing import TypedDict
class User(TypedDict):
name: str
age: int
def greet(user: User) -> str:
return f"Hello, {user['name']}"
Utiliser les vérificateurs de types statiques
Les type hints ne sont utiles que si vous les vérifiez. Les outils populaires incluent mypy, pyright et pyre. Voyons comment utiliser mypy.
- Installez mypy :
pip install mypy - Exécutez-le sur votre code :
mypy your_script.py - Corrigez les erreurs signalées.
Par exemple, étant donné :
def add(a: int, b: int) -> int:
return a + b
add("1", "2")
mypy signalera : error: Argument 1 to "add" has incompatible type "str"; expected "int".
Vous pouvez configurer mypy via un fichier mypy.ini ou pyproject.toml pour appliquer des vérifications plus strictes.
Bonnes pratiques pour les type hints
- Soyez cohérent : Annotez toutes les fonctions et méthodes publiques.
- Utilisez
Anyavec parcimonie : Cela désactive la vérification de type pour cette valeur. - Préférez des types concrets à
Anyouobject. - Utilisez
Optionalpour les valeurs qui peuvent être None. - Tirez parti de
Protocolpour le sous-typage structurel (duck typing avec sécurité de type). - Maintenez les type hints à jour lors du refactoring.
- Exécutez un vérificateur de types dans la CI pour détecter les problèmes tôt.
Pièges courants et comment les éviter
- Ignorer les erreurs de type : Ne vous contentez pas de faire taire mypy ; comprenez et corrigez le problème.
- Abuser de
Any: Cela va à l'encontre de l'objectif des type hints. - Oublier d'annoter les types de retour : Surtout pour les fonctions qui renvoient None.
- Utiliser des arguments par défaut mutables avec des type hints : C'est un piège Python distinct, mais les type hints ne le détecteront pas.
- Ne pas mettre à jour les hints après des modifications : Cela conduit à une fausse confiance.
Les type hints en pratique : un petit exemple
Considérez une fonction qui traite une liste de nombres et renvoie la moyenne. Sans type hints, les types attendus ne sont pas clairs.
def average(numbers):
return sum(numbers) / len(numbers)
Avec des type hints :
from typing import List
def average(numbers: List[float]) -> float:
return sum(numbers) / len(numbers)
Maintenant, si quelqu'un passe une liste de chaînes de caractères, mypy le signalera.
Intégrer les type hints dans votre flux de travail
Pour tirer le meilleur parti des type hints, intégrez-les dans votre processus de développement :
- Ajoutez progressivement des type hints aux bases de code existantes.
- Configurez votre IDE pour afficher les erreurs de type.
- Ajoutez une étape de vérification de types à votre pipeline CI.
- Utilisez des hooks pre-commit pour exécuter mypy avant les commits.
Par exemple, une étape simple dans un workflow GitHub Actions :
- name: Type check
run: mypy .
FAQ
Les type hints affectent-ils les performances à l'exécution ?
Non, les type hints sont ignorés à l'exécution. Ils sont stockés dans __annotations__ mais n'ont aucun impact sur la vitesse d'exécution.
Puis-je utiliser les type hints dans des versions plus anciennes de Python ?
Les type hints ont été introduits dans Python 3.5. Pour les versions plus anciennes, vous pouvez utiliser des annotations sous forme de commentaires (par exemple, # type: int), mais il est recommandé de passer à une version de Python prise en charge.
Quelle est la différence entre List et list dans les type hints ?
List de typing est utilisé dans Python 3.5-3.8. Dans Python 3.9+, vous pouvez utiliser directement le list natif. Les deux sont équivalents pour la vérification de type.
Prêt à améliorer la qualité de votre code ? Commencez par ajouter des type hints à une fonction dès aujourd'hui et exécutez mypy pour constater les bénéfices. Pour plus d'outils de développement, découvrez notre JSON Formatter pour embellir et valider vos données JSON sans effort.