Pourquoi Type hints en Python ?
Contexte réel : pourquoi un dev a besoin de ca au quotidien Dans le développement moderne, l'évolution rapide des outils et frameworks peut rendre difficile la maintenance et la compréhension du code. Les type hints en Python offrent une couche supplémentaire de sécurité et de lisibilité, permettant aux développeurs de comprendre rapidement les types de données attendues et retournées par les fonctions, les méthodes et les classes.
Un cas d'usage concret en 2-3 phrases En travaillant sur un projet open source, vous avez reçu une contribution qui utilise une fonction que vous n'avez jamais vue. Grâce aux type hints inclus dans la fonction, vous pouvez instantanément comprendre quels types de données sont nécessaires et ce que la fonction retourne, évitant ainsi des erreurs potentielles.
Prerequis
Connaissances Nécessaires :
- Comprendre les bases du langage Python (structures de données, fonctions, classes)
- Connaissance élémentaire sur les types de base en Python (
int,float,str,list,dict)
Outils à Installer :
- Version recommandée de Python : Python 3.5 ou plus récente
- Environnement virtuel pour isoler les dépendances :
python3 -m venv myenv - Activer l'environnement virtuel :
source myenv/bin/activate # macOS/Linux .\myenv\Scripts\activate # Windows
Concepts fondamentaux
1. Définition et Syntaxe de Type Hinting
Les type hints en Python sont ajoutés à la fin des paramètres et du retour d'une fonction. Elles sont déclarées avec un deux-points : suivis du type attendu.
def greet(name: str) -> str:
return f"Hello, {name}!"
2. Types Primitifs
Python offre de nombreux types primitifs qui peuvent être utilisés pour les type hints.
age: int = 30
##
price: float = 19.99
##
username: str = "john_doe"
##
is_active: bool = True
3. Types de Collections
Les types hints peuvent également être utilisés pour les collections comme list, tuple et dict.
numbers: list[int] = [1, 2, 3, 4, 5]
##
person_info: tuple[str, int] = ("John", 30)
##
user_data: dict[str, str] = {"name": "Alice", "email": "alice@example.com"}
4. Types Avancés
Python offre également des types avancés comme Optional, Union et Callable.
from typing import Optional, Union, Callable
##
age: Optional[int] = None
##
value: Union[int, str] = 42
##
def add_one(x: str) -> int:
return int(x) + 1
5. Classes et Type Hinting
Vous pouvez également utiliser des type hints avec les classes pour spécifier le type de la variable.
class User:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
##
def greet_user(user: User) -> str:
return f"Hello, {user.name}! You are {user.age} years old."
##
alice = User("Alice", 30)
greeting = greet_user(alice)
6. Type Hinting dans les Modules
Vous pouvez utiliser des type hints pour documenter et spécifier les types de vos modules.
from typing import Union
def add(x: Union[int, float], y: Union[int, float]) -> Union[int, float]:
return x + y
def multiply(x: Union[int, float], y: Union[int, float]) -> Union[int, float]:
return x * y
Mise en pratique : projet fil rouge
Projet Fil Rouge : Un Mini-Gestionnaire de Tâches
Étape 1 : Structure du Projet
mkdir task_manager
cd task_manager
python3 -m venv venv
source venv/bin/activate # macOS/Linux
.\venv\Scripts\activate # Windows
pip install typing-extensions
Étape 2 : Création des Fichiers Créez les fichiers suivants :
task_manager/__init__.pytask_manager/task.pytask_manager/main.py
Étape 3 : Définition de la Classe Task
from typing import Optional, Union
class Task:
def __init__(self, title: str, description: Optional[str] = None, completed: bool = False):
self.title = title
self.description = description
self.completed = completed
def mark_as_completed(self) -> None:
self.completed = True
def __str__(self) -> str:
status = "Done" if self.completed else "Pending"
return f"{status}: {self.title} - {self.description}"
Étape 4 : Définition de la Classe TaskManager
from typing import List, Optional
from .task import Task
class TaskManager:
def __init__(self):
self.tasks: List[Task] = []
def add_task(self, task: Task) -> None:
self.tasks.append(task)
def remove_task(self, index: int) -> None:
if 0 <= index < len(self.tasks):
del self.tasks[index]
def get_tasks(self) -> List[str]:
return [str(task) for task in self.tasks]
Étape 5 : Utilisation du Gestionnaire de Tâches
from .task_manager import TaskManager
def main():
task_manager = TaskManager()
task1 = Task("Complete Python project")
task2 = Task("Read a book", "Learn about design patterns")
task_manager.add_task(task1)
task_manager.add_task(task2)
print("Tasks:")
for task in task_manager.get_tasks():
print(task)
if __name__ == "__main__":
main()
Étape 6 : Exécution du Script
python -m task_manager.main
Erreurs fréquentes et debugging
1. Erreur de type incorrect
Code Incorrect
def add_numbers(a, b):
return a + b
Message d'erreur
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Code Correct
from typing import Union
def add_numbers(a: int, b: int) -> int:
return a + b
2. Erreur de retour incorrect
Code Incorrect
def greet(name):
return f"Hello, {name}"
Message d'erreur
TypeError: greet() should return str but returning None
Code Correct
from typing import Optional, Union
def greet(name: str) -> str:
return f"Hello, {name}"
3. Erreur de type dans une fonction avec des arguments optionnels
Code Incorrect
from typing import Optional
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
Message d'erreur
TypeError: greet() takes from 1 to 2 positional arguments but 3 were given
Code Correct
from typing import Optional
def greet(name: str, greeting: Optional[str] = "Hello") -> str:
return f"{greeting}, {name}!"
4. Erreur de type dans une fonction avec des arguments par défaut
Code Incorrect
from typing import Union
def add_numbers(a: int, b: int = 1) -> int:
return a + b
Message d'erreur
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Code Correct
from typing import Optional, Union
def add_numbers(a: int, b: int = 1) -> int:
return a + b
5. Erreur de type dans une fonction avec des arguments nommés
Code Incorrect
from typing import Union
def add_numbers(a: int, b: int) -> int:
return a + b
Message d'erreur
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Code Correct
from typing import Optional, Union
def add_numbers(a: int, b: int) -> int:
return a + b
Pour aller plus loin
1. Utiliser les Type Hints avec des IDEs (IntelliJ IDEA, PyCharm)
Les IDEs modernes comme IntelliJ IDEA et PyCharm offrent une meilleure compréhension des type hints, ce qui aide à détecter les erreurs en temps réel.
2. Utiliser mypy pour la vérification statique
Le linter mypy permet de vérifier les type hints au moment de la compilation.
pip install mypy
mypy task_manager/
3. Utiliser les Type Hints avec des Frameworks (Django, FastAPI)
La plupart des frameworks modernes en Python utilisent les type hints pour améliorer leur lisibilité et leur maintenabilité.
Défi Pratique : Créer une API de Blog avec FastAPI
- Installez
FastAPIetUvicorn. - Créez un fichier
main.pyavec les endpoints suivants :/posts: GET pour récupérer tous les posts/post/{id}: GET pour récupérer un post spécifique/post: POST pour créer un nouveau post/post/{id}: PUT pour mettre à jour un post/post/{id}: DELETE pour supprimer un post
Cela vous permettra de pratiquer la création d'une API complète avec les type hints en Python et FastAPI.