Guide de débutant sur les génériques en Python

Salut là, futur maître de Python ! Aujourd'hui, nous allons entreprendre un voyage passionnant dans le monde des génériques Python. Ne t'inquiète pas si tu es nouveau dans le monde de la programmation – je serai ton guide amical, expliquant tout pas à pas. Alors, prends une tasse de ta boisson favorite et plongeons dedans !

Python - Generics

Qu'est-ce que les génériques ?

Avant de commencer à coder, comprenons ce que sont les génériques. Imagine que tu as une boîte magique qui peut contenir tout type d'objet - des jouets, des livres, ou même des cookies. C'est essentiellement ce que font les génériques en programmation. Ils nous permettent d'écrire du code flexible qui peut fonctionner avec différents types de données.

Définir une fonction générique

Commençons par créer une fonction générique. En Python, nous utilisons TypeVar du module typing pour définir des types génériques.

from typing import TypeVar

T = TypeVar('T')

def print_item(item: T) -> None:
print(f"L'objet est : {item}")

Dans cet exemple, T est notre type générique. La fonction print_item peut maintenant accepter tout type de données. Décomposons cela :

  1. Nous importons TypeVar du module typing.
  2. Nous créons une variable de type T.
  3. Notre fonction print_item prend un argument item de type T.
  4. La fonction imprime simplement l'objet.

Appeler la fonction générique avec différents types de données

Maintenant, voyons notre fonction générique en action !

print_item(42)
print_item("Hello, Génériques !")
print_item([1, 2, 3])

Sortie :

L'objet est : 42
L'objet est : Hello, Génériques !
L'objet est : [1, 2, 3]

Comme vous pouvez le voir, notre fonction fonctionne avec différents types de données - des entiers, des chaînes de caractères, et même des listes. C'est comme avoir un couteau suisse dans votre boîte à outils de code !

Définir une classe générique

Maintenant que nous maîtrisons les fonctions génériques, levons le niveau et créons une classe générique. Imaginez que nous construisons un système de stockage simple qui peut contenir tout type d'objet.

from typing import Generic, TypeVar

T = TypeVar('T')

class Box(Generic[T]):
def __init__(self, item: T):
self.item = item

def get_item(self) -> T:
return self.item

def set_item(self, new_item: T) -> None:
self.item = new_item

Décomposons cette boîte magique :

  1. Nous définissons notre classe Box comme Generic[T].
  2. La méthode __init__ prend un item de type T.
  3. get_item retourne l'objet stocké.
  4. set_item nous permet de changer l'objet.

Maintenant, mettons notre boîte à l'épreuve :

# Une boîte d'entiers
int_box = Box(42)
print(int_box.get_item())  # Sortie : 42

# Une boîte de chaînes de caractères
str_box = Box("Hello, Classe Générique !")
print(str_box.get_item())  # Sortie : Hello, Classe Générique !

# Changer l'objet dans la boîte
int_box.set_item(100)
print(int_box.get_item())  # Sortie : 100

C'est génial, non ? Nous pouvons créer des boîtes pour stocker différents types d'objets, et Python assure la sécurité des types pour nous.

La puissance des génériques

Les génériques peuvent sembler un peu abstraits au départ, mais ils sont incroyablement puissants. Ils nous permettent d'écrire du code à la fois flexible et sûr. Imaginez que vous construisez une grande application - les génériques peuvent vous aider à créer des composants réutilisables qui fonctionnent avec divers types de données, vous économisant du temps et réduisant les erreurs.

Voici un exemple plus complexe pour illustrer cette puissance :

from typing import Generic, TypeVar, List

T = TypeVar('T')

class Storage(Generic[T]):
def __init__(self):
self.items: List[T] = []

def add_item(self, item: T) -> None:
self.items.append(item)

def get_items(self) -> List[T]:
return self.items

def get_last_item(self) -> T:
if self.items:
return self.items[-1]
raise IndexError("Le stockage est vide")

# Utilisation de notre classe générique Storage
int_storage = Storage[int]()
int_storage.add_item(1)
int_storage.add_item(2)
int_storage.add_item(3)

str_storage = Storage[str]()
str_storage.add_item("Apple")
str_storage.add_item("Banana")
str_storage.add_item("Cherry")

print(int_storage.get_items())  # Sortie : [1, 2, 3]
print(str_storage.get_last_item())  # Sortie : Cherry

Dans cet exemple, nous avons créé une classe générique Storage qui peut contenir des listes de tout type. Nous avons ensuite créé des stocks séparés pour les entiers et les chaînes de caractères, démontrant la flexibilité de notre classe générique.

Conclusion

Félicitations ! Tu viens de faire tes premiers pas dans le monde des génériques Python. Nous avons couvert les fonctions génériques, les classes génériques, et même construit un système de stockage flexible. Souviens-toi, comme avec n'importe quel outil puissant, les génériques nécessitent de la pratique pour être maîtrisés. Ne sois pas découragé si cela ne fonctionne pas immédiatement - continue à expérimenter et tu verras bientôt la magie des génériques dans ton propre code.

Pour conclure, voici un tableau récapitulatif des méthodes clés que nous avons apprises :

Méthode Description
TypeVar('T') Crée une variable de type pour une utilisation générique
Generic[T] Définit une classe générique
__init__(self, item: T) Initialise une classe générique avec un objet de type T
get_item(self) -> T Retourne un objet de type T
set_item(self, new_item: T) -> None Définit un nouvel objet de type T
add_item(self, item: T) -> None Ajoute un objet de type T à une collection
get_items(self) -> List[T] Retourne une liste d'objets de type T
get_last_item(self) -> T Retourne le dernier objet de type T dans une collection

Continuez à coder, continuez à apprendre, et souvenez-vous - avec les génériques, vos pouvoirs Python sont illimités ! Bon codage, futurs sorciers Python !

Credits: Image by storyset