Le mot-clé yield

Le mot-clé yield est utilisé dans une fonction pour la transformer en générateur :

def generate_numbers(n):
    for i in range(n):
        yield i * i  # Renvoie le carré de chaque nombre jusqu'à n

Différence avec return

Une fonction classique calcule un résultat, le renvoie et termine son exécution. Une fois l'exécution terminée, les variables locales à la fonction n'existent plus.

L'utilisation de yield va modifier son comportement :

  • Lorsque yield est atteint, le générateur se met en pause et envoie la valeur à l'appelant

  • L'état du générateur est sauvegardé

  • Lorsque l'appelant demande la valeur suivante (par exemple avec une boucle), le générateur reprend son exécution

def simple_generateur():
    print("-> Début de la fonction")
    yield 1
    print("-> Reprise après le premier yield")
    yield 2
    print("-> Reprise après le second yield")
    yield 3
    print("-> Fin de la fonction")

# L'appel à la fonction ne l'exécute pas, il crée un objet générateur.
mon_generateur = simple_generateur()

# La boucle for est la manière la plus courante de consommer un générateur.
# Elle appelle next() automatiquement en arrière-plan.
for valeur in mon_generateur:
    print(f"Valeur reçue : {valeur}\n")

# Résultat attendu :
# -> Début de la fonction
# Valeur reçue : 1
#
# -> Reprise après le premier yield
# Valeur reçue : 2
#
# -> Reprise après le second yield
# Valeur reçue : 3
#
# -> Fin de la fonction
Un instant

Contrôle manuel avec next()

Pour bien voir le mécanisme, on peut utiliser la fonction next() manuellement (ce que fait Python en arrière plan quand on utilise une boucle for). Ce qui permet de récupérer les valeurs une par une :

def simple_generateur():
    print("-> Début de la fonction")
    yield 1
    print("-> Reprise après le premier yield")
    yield 2
    print("-> Reprise et fin après le second yield")


# On recrée le générateur
generateur_manuel = simple_generateur()

# Premier appel
print(f"Appel next() 1: {next(generateur_manuel)}")
# -> Début de la fonction
# Appel next() 1: 1

# Deuxième appel
print(f"Appel next() 2: {next(generateur_manuel)}")
# -> Reprise après le premier yield
# Appel next() 2: 2

# Si on appelle next() après que le générateur soit épuisé,
# une exception StopIteration est levée.

next(generateur_manuel)
Un instant

Pourquoi utiliser yield ?

  • Efficacité mémoire : permet de traiter des grands ensembles de données, car contrairement à une liste, un générateur ne charge qu'un élément en mémoire à la fois

  • Calculs paresseux : Les valeurs sont générées uniquement lorsqu'elles sont demandées

Bravo, tu es prêt à passer à la suite

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.