Que sont les Type Hints en Python
Les Type Hints (annotations de type) sont un système permettant d'indiquer les types de données attendus dans le code Python. Ils améliorent la lisibilité, la fiabilité et la qualité des logiciels. Bien que Python reste un langage dynamiquement typé, la possibilité de spécifier explicitement les types permet d'éviter de nombreuses erreurs dès la phase de développement.
Pourquoi utiliser les annotations de type
Python est réputé pour sa flexibilité, mais cela peut entraîner des bugs cachés dus à des types de données inattendus. Prenons un exemple sans annotations :
def add(a, b):
return a + b
print(add(5, 10)) # 15
print(add("5", "10")) # '510' — résultat inattendu
L'expression add("5", "10") ne génère pas d'erreur, mais le résultat peut surprendre le développeur.
Les Type Hints permettent de :
- Spécifier explicitement les types des arguments et des valeurs de retour
- Améliorer la lisibilité du code pour l'équipe de développement
- Analyser statiquement le code pour détecter les erreurs avant l'exécution
- Bénéficier d'une autocomplétion plus précise dans les IDE
- Documenter l'API sans commentaires supplémentaires
Exemples de base des Type Hints
Annotations de fonctions
def add(a: int, b: int) -> int:
return a + b
def calculate_area(radius: float) -> float:
return 3.14159 * radius ** 2
def format_greeting(name: str) -> str:
return f"Bonjour, {name} !"
Annotations de variables
name: str = "Alice"
age: int = 30
pi: float = 3.14159
is_active: bool = True
Travailler avec les collections
from typing import List, Dict, Tuple, Set
def process_scores(scores: List[int]) -> float:
return sum(scores) / len(scores)
def get_user_data() -> Dict[str, str]:
return {"name": "Jean", "email": "jean@exemple.com"}
def get_coordinates() -> Tuple[float, float]:
return (10.5, 20.3)
def unique_values(items: List[str]) -> Set[str]:
return set(items)
Fonctionnalités avancées des Type Hints
Optional et Union
from typing import Optional, Union
def greet(name: Optional[str] = None) -> str:
if name:
return f"Bonjour, {name} !"
return "Bonjour, invité !"
def process_value(value: Union[int, float, str]) -> str:
return str(value)
# En Python 3.10+, vous pouvez utiliser l'opérateur |
def process_new_syntax(value: int | float | str) -> str:
return str(value)
Types Callable
from typing import Callable
def apply_function(func: Callable[[int, int], int], a: int, b: int) -> int:
return func(a, b)
def multiply(x: int, y: int) -> int:
return x * y
result = apply_function(multiply, 5, 3) # 15
Types génériques (Generic)
from typing import TypeVar, Generic, List
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:
if not self.items:
raise IndexError("La pile est vide")
return self.items.pop()
def is_empty(self) -> bool:
return len(self.items) == 0
# Utilisation
int_stack = Stack[int]()
int_stack.push(42)
Annotations dans les classes
from typing import List, Optional
from dataclasses import dataclass
class Person:
def __init__(self, name: str, age: int, email: Optional[str] = None) -> None:
self.name = n