Les Fonctions def en Python
Les Fonctions def en Python
Ce document explique toutes les façons de définir et d’utiliser les fonctions en Python
: comment les créer, comment les appeler, où se situe le programme principal par
rapport au sous-programme, les différents types de paramètres, quand utiliser return,
comment utiliser break et sa portée, et enfin comment combiner def avec des boucles
imbriquées.
1. Qu’est-ce qu’une fonction ?
Une fonction est un bloc de code réutilisable, identifié par un nom, qui exécute une
tâche précise. On la définit avec le mot-clé def. Une fonction est aussi appelée un sous-
programme, car elle est une portion de code indépendante que le programme principal
peut appeler autant de fois que nécessaire.
Avantages : éviter de répéter du code, rendre le programme plus lisible, faciliter les
corrections et les tests.
2. Toutes les manières de définir une fonction avec
def
2.1. Fonction sans paramètre et sans retour
def dire_bonjour():
print("Bonjour tout le monde !")
dire_bonjour()
Quand l’utiliser : pour une action simple qui ne dépend d’aucune donnée extérieure
(afficher un message fixe, par exemple).
2.2. Fonction sans paramètre, mais avec un retour
def valeur_fixe():
return 42
x = valeur_fixe()
print(x) # 42
2.3. Fonction avec un seul paramètre
def saluer(nom):
print(f"Bonjour {nom} !")
saluer("Alice")
2.4. Fonction avec plusieurs paramètres
SOUMBOU IYO GILBERT JUDE GI1/B ECES
def addition(a, b):
return a + b
print(addition(3, 4)) # 7
2.5. Fonction avec un ou plusieurs paramètres à valeur par défaut
def puissance(base, exposant=2):
return base ** exposant
print(puissance(5)) # 25 (exposant non précisé -> valeur par défaut 2)
print(puissance(5, 3)) # 125
Quand l’utiliser : quand un paramètre a une valeur “habituelle” que l’on ne veut pas
répéter à chaque appel.
2.6. Fonction avec un nombre variable de paramètres (*args)
def somme(*args):
return sum(args)
print(somme(1, 2, 3, 4)) # 10
Quand l’utiliser : quand on ne connaît pas à l’avance le nombre d’arguments à fournir.
2.7. Fonction avec des paramètres nommés variables (**kwargs)
def afficher_profil(**kwargs):
for cle, valeur in [Link]():
print(f"{cle} : {valeur}")
afficher_profil(nom="Alice", age=25, ville="Paris")
2.8. Fonction avec annotations de type (facultatif, à but indicatif)
def multiplier(a: int, b: int) -> int:
return a * b
print(multiplier(3, 4)) # 12
Remarque : les annotations (: int, -> int) ne sont pas vérifiées automatiquement
par Python ; elles servent uniquement à documenter le code.
2.9. Fonction imbriquée (une fonction définie à l’intérieur d’une
autre)
def exterieure():
def interieure():
print("Je suis à l'intérieur !")
interieure()
exterieure()
Quand l’utiliser : quand une fonction n’est utile qu’à l’intérieur d’une autre, et ne doit
pas être accessible depuis l’extérieur.
SOUMBOU IYO GILBERT JUDE GI1/B ECES
2.10. Fonction récursive (qui s’appelle elle-même)
def factorielle(n):
if n <= 1:
return 1
return n * factorielle(n - 1)
print(factorielle(5)) # 120
Quand l’utiliser : pour des problèmes qui se décomposent naturellement en sous-
problèmes identiques plus petits.
2.11. Fonction avec docstring (documentation intégrée)
def carre(n):
"""Retourne le carré du nombre n."""
return n ** 2
print(carre.__doc__) # Retourne le carré du nombre n.
3. Toutes les manières d’appeler une fonction
3.1. Appel simple avec arguments positionnels
def addition(a, b):
return a + b
print(addition(3, 4)) # les valeurs sont associées dans l'ordre : a=3, b=4
3.2. Appel avec arguments nommés (mots-clés)
def presenter(nom, age):
print(f"{nom} a {age} ans")
presenter(age=25, nom="Alice") # l'ordre n'a plus d'importance
3.3. Appel en mélangeant positionnels et nommés
def presenter(nom, age, ville):
print(f"{nom}, {age} ans, habite à {ville}")
presenter("Alice", ville="Paris", age=25)
Règle : les arguments positionnels doivent toujours être placés avant les arguments
nommés.
3.4. Appel en omettant les paramètres ayant une valeur par défaut
def puissance(base, exposant=2):
return base ** exposant
print(puissance(5)) # exposant omis -> 25
print(puissance(5, 3)) # exposant précisé -> 125
SOUMBOU IYO GILBERT JUDE GI1/B ECES
3.5. Appel avec une liste ou un tuple “déballé” (*)
def addition(a, b, c):
return a + b + c
valeurs = [1, 2, 3]
print(addition(*valeurs)) # équivalent à addition(1, 2, 3)
3.6. Appel avec un dictionnaire “déballé” (**)
def presenter(nom, age):
print(f"{nom} a {age} ans")
infos = {"nom": "Alice", "age": 25}
presenter(**infos) # équivalent à presenter(nom="Alice", age=25)
3.7. Appel imbriqué (le résultat d’une fonction utilisé comme
argument d’une autre)
def carre(n):
return n * n
def racine(n):
return n ** 0.5
print(racine(carre(4))) # carre(4) est calculé d'abord -> racine(16) -> 4.0
3.8. Stocker le résultat d’un appel dans une variable
def addition(a, b):
return a + b
resultat = addition(10, 5)
print(resultat) # 15
3.9. Appeler une fonction plusieurs fois dans une boucle
def carre(n):
return n * n
for i in range(1, 5):
print(carre(i))
# 1 4 9 16
4. Le programme principal et le sous-programme
En Python, un sous-programme est simplement une fonction (un bloc def). Le
programme principal est la partie du fichier qui s’exécute réellement, en dehors de
toute fonction : c’est là que les fonctions sont appelées.
# =========================================
# SOUS-PROGRAMMES (définitions de fonctions)
# =========================================
def saluer(nom):
return f"Bonjour {nom} !"
SOUMBOU IYO GILBERT JUDE GI1/B ECES
def calculer_carre(n):
return n * n
# =========================================
# PROGRAMME PRINCIPAL
# (le code qui s'exécute réellement)
# =========================================
message = saluer("Alice")
print(message)
resultat = calculer_carre(6)
print(resultat)
À retenir : - Tout ce qui est écrit à l’intérieur d’un def (indenté) fait partie du sous-
programme (la fonction) : il ne s’exécute que lorsqu’on appelle la fonction. - Tout ce
qui est écrit sans indentation, en dehors des fonctions, fait partie du programme
principal : il s’exécute directement, dans l’ordre, dès que le script est lancé.
4.1. La convention if __name__ == "__main__":
Pour bien séparer visuellement le programme principal des sous-programmes (surtout si
le fichier peut être réutilisé comme module ailleurs), on utilise souvent :
def saluer(nom):
return f"Bonjour {nom} !"
def calculer_carre(n):
return n * n
# Ce bloc ne s'exécute QUE si le fichier est lancé directement
# (pas si le fichier est importé depuis un autre programme)
if __name__ == "__main__":
print(saluer("Alice"))
print(calculer_carre(6))
Quand l’utiliser : dès qu’on écrit un fichier qui pourrait être à la fois exécuté seul et
importé comme module dans un autre programme.
5. Les différents types de paramètres
5.1. Paramètres positionnels (classiques)
def presenter(nom, age):
print(f"{nom} a {age} ans")
presenter("Alice", 25) # associés dans l'ordre d'écriture
5.2. Paramètres nommés (mots-clés)
def presenter(nom, age):
print(f"{nom} a {age} ans")
presenter(age=25, nom="Alice") # l'ordre n'a plus d'importance
5.3. Paramètres avec valeur par défaut
SOUMBOU IYO GILBERT JUDE GI1/B ECES
def presenter(nom, age=18):
print(f"{nom} a {age} ans")
presenter("Bob") # age prend la valeur par défaut 18
presenter("Bob", 30) # age est explicitement 30
5.4. Paramètres variables positionnels (*args)
def somme(*args):
total = 0
for nombre in args:
total += nombre
return total
print(somme(1, 2, 3, 4, 5)) # 15
5.5. Paramètres variables nommés (**kwargs)
def creer_fiche(**kwargs):
for cle, valeur in [Link]():
print(f"{cle} : {valeur}")
creer_fiche(nom="Alice", age=25, ville="Paris")
5.6. Combinaison de tous les types de paramètres dans une seule
fonction
def fonction_complete(a, b, c=10, *args, **kwargs):
print("a =", a)
print("b =", b)
print("c =", c)
print("args =", args)
print("kwargs =", kwargs)
fonction_complete(1, 2, 3, 4, 5, ville="Paris", pays="France")
# a = 1
# b = 2
# c = 3
# args = (4, 5)
# kwargs = {'ville': 'Paris', 'pays': 'France'}
Règle d’ordre obligatoire : paramètres positionnels → paramètres avec valeur par
défaut → *args → **kwargs.
6. Quand utiliser return : toutes les manières et sa
portée
6.1. Retourner une valeur simple
def carre(n):
return n ** 2
print(carre(5)) # 25
Quand l’utiliser : dès que la fonction doit produire un résultat réutilisable ailleurs dans
SOUMBOU IYO GILBERT JUDE GI1/B ECES
le programme.
6.2. return sans valeur (arrêter une fonction plus tôt)
def verifier_positif(n):
if n < 0:
print("Nombre négatif, arrêt de la fonction")
return # sort de la fonction immédiatement, sans valeur
print("Traitement du nombre :", n)
verifier_positif(-5)
6.3. Retourner plusieurs valeurs à la fois (tuple implicite)
def min_et_max(liste):
return min(liste), max(liste)
plus_petit, plus_grand = min_et_max([4, 7, 2, 9, 1])
print(plus_petit, plus_grand) # 1 9
6.4. return conditionnel (sortie anticipée / garde-fou)
def diviser(a, b):
if b == 0:
return None # sortie immédiate si division impossible
return a / b
print(diviser(10, 0)) # None
print(diviser(10, 2)) # 5.0
Quand l’utiliser : pour éviter un traitement inutile ou une erreur lorsque les données
ne permettent pas de continuer.
6.5. return à l’intérieur d’une boucle
def rechercher(liste, cible):
for i, valeur in enumerate(liste):
if valeur == cible:
return i # sort de la fonction ET de la boucle en une seule
fois
return -1
print(rechercher([10, 20, 30], 20)) # 1
6.6. Une fonction sans return renvoie automatiquement None
def afficher(message):
print(message)
resultat = afficher("Bonjour")
print(resultat) # None (car afficher() n'a pas de return)
6.7. La portée de return : il n’arrête QUE la fonction dans laquelle il
se trouve
def fonction_interne():
return "Résultat interne"
SOUMBOU IYO GILBERT JUDE GI1/B ECES
def fonction_externe():
valeur = fonction_interne()
print("Avant le retour de fonction_interne") # s'exécute quand même !
return valeur
print(fonction_externe())
# Avant le retour de fonction_interne
# Résultat interne
À retenir : return dans fonction_interne() n’arrête que fonction_interne(). La
fonction appelante (fonction_externe) continue normalement après avoir reçu le
résultat — le print s’exécute bien avant que fonction_externe ne se termine à son
tour.
6.8. return vs break : ne pas confondre
Instruction Ce qu’elle arrête
break uniquement la boucle la plus proche
return toute la fonction, y compris toutes les boucles qu’elle contient
def trouver_premiere_paire(liste):
for i in liste:
for j in liste:
if i != j and (i + j) % 2 == 0:
return (i, j) # sort direct de TOUTE la fonction (2 boucles
comprises)
return None
print(trouver_premiere_paire([1, 2, 3, 4])) # (1, 3)
7. Toutes les manières d’utiliser break et sa portée
7.1. break simple dans une boucle
for i in range(10):
if i == 4:
break
print(i)
# 0 1 2 3
Quand l’utiliser : pour arrêter une boucle dès qu’une condition précise est atteinte.
7.2. break dans une boucle à l’intérieur d’une fonction
def premiere_valeur_negative(liste):
for valeur in liste:
if valeur < 0:
print("Négatif trouvé :", valeur)
break
print("Fin de la fonction")
premiere_valeur_negative([3, 5, -2, 8])
# Négatif trouvé : -2
# Fin de la fonction
SOUMBOU IYO GILBERT JUDE GI1/B ECES
Remarque : contrairement à return, break ne fait qu’arrêter la boucle — le reste de la
fonction (ici le print("Fin de la fonction")) continue à s’exécuter normalement.
7.3. La portée de break : il n’arrête que la boucle la plus proche
def demonstration():
for i in range(3):
for j in range(3):
if j == 1:
break # arrête seulement la boucle "for j"
print(f"i={i}, j={j}")
print(f"-- fin du tour i={i} --")
demonstration()
# i=0, j=0
# -- fin du tour i=0 --
# i=1, j=0
# -- fin du tour i=1 --
# i=2, j=0
# -- fin du tour i=2 --
À retenir : la boucle extérieure (for i) n’est jamais interrompue par le break de la
boucle intérieure.
7.4. Sortir de plusieurs boucles imbriquées dans une fonction grâce à
return
def trouver_produit(cible, limite):
for i in range(limite):
for j in range(limite):
if i * j == cible:
return (i, j) # sort de TOUTES les boucles ET de la fonction
return None
print(trouver_produit(6, 5)) # (1, 6) ou une autre paire valide selon l'ordre
parcouru
Quand l’utiliser : dès que des boucles imbriquées sont placées dans une fonction,
return est le moyen le plus simple et le plus propre de sortir de toutes les boucles en
une seule instruction (plus simple qu’un break combiné à un drapeau booléen).
7.5. Récapitulatif break vs sa portée
Situation Effet
Une seule boucle break arrête complètement la boucle
Boucles imbriquées break n’arrête que la boucle la plus intérieure
Boucles imbriquées dans une return permet de sortir de toutes les boucles et
fonction de la fonction d’un seul coup
8. Utiliser def avec des boucles imbriquées
Une fonction peut contenir n’importe quelle combinaison de boucles for et while, y
compris imbriquées (une boucle à l’intérieur d’une autre).
8.1. Fonction avec deux boucles for imbriquées (for dans for)
SOUMBOU IYO GILBERT JUDE GI1/B ECES
def table_multiplication(n):
for i in range(1, n + 1):
for j in range(1, n + 1):
print(f"{i} x {j} = {i*j}")
table_multiplication(2)
# 1 x 1 = 1
# 1 x 2 = 2
# 2 x 1 = 2
# 2 x 2 = 4
Quand l’utiliser : pour parcourir une structure à deux dimensions (grille, matrice) à
l’intérieur d’une fonction.
8.2. Fonction avec deux boucles while imbriquées (while dans while)
def damier(taille):
i = 0
while i < taille:
j = 0
ligne = ""
while j < taille:
ligne += "X" if (i + j) % 2 == 0 else "O"
j += 1
print(ligne)
i += 1
damier(4)
# XOXO
# OXOX
# XOXO
# OXOX
Quand l’utiliser : quand le nombre d’itérations dépend d’une condition plus complexe
qu’un simple compteur, à chaque niveau d’imbrication.
8.3. Fonction avec un for imbriqué dans un while
def afficher_lignes_croissantes(nb_lignes):
ligne_actuelle = 1
while ligne_actuelle <= nb_lignes:
for colonne in range(ligne_actuelle):
print("*", end="")
print()
ligne_actuelle += 1
afficher_lignes_croissantes(4)
# *
# **
# ***
# ****
Quand l’utiliser : quand la boucle extérieure dépend d’une condition d’arrêt variable
(while), mais que chaque étape nécessite un parcours simple et connu à l’avance (for).
8.4. Fonction avec un while imbriqué dans un for
def compte_a_rebours_multiple(depart, nb_series):
for serie in range(1, nb_series + 1):
print(f"Série {serie} :")
SOUMBOU IYO GILBERT JUDE GI1/B ECES
n = depart
while n > 0:
print(" ", n)
n -= 1
compte_a_rebours_multiple(3, 2)
# Série 1 :
# 3
# 2
# 1
# Série 2 :
# 3
# 2
# 1
Quand l’utiliser : quand on répète un nombre de fois connu (for) un traitement dont la
durée interne dépend d’une condition (while).
8.5. Tableau récapitulatif des combinaisons
Combinaison Exemple d’usage typique
for dans for table de multiplication, matrice, grille
while dans while damier, traitement conditionnel à deux niveaux
nombre d’étapes variable, chaque étape ayant un nombre fixe
for dans while
de sous-actions
while dans for nombre d’étapes fixe, chaque étape ayant une durée variable
9. L’imbrication des fonctions (def à l’intérieur d’un
autre def)
Tout comme les boucles, les fonctions peuvent être imbriquées : on peut définir une
fonction à l’intérieur d’une autre. Il existe deux façons d’imbriquer plusieurs fonctions :
en profondeur (en chaîne) : une fonction contient une fonction, qui elle-même en
contient une autre (niveau 1 → niveau 2 → niveau 3…) ;
en largeur : une fonction principale contient plusieurs sous-fonctions
indépendantes, définies côte à côte.
9.1. Imbrication à 1 def (une seule fonction imbriquée)
def fonction_principale():
def sous_fonction():
print("Je suis la sous-fonction")
print("Avant l'appel de la sous-fonction")
sous_fonction()
print("Après l'appel de la sous-fonction")
fonction_principale()
# Avant l'appel de la sous-fonction
# Je suis la sous-fonction
# Après l'appel de la sous-fonction
Quand l’utiliser : quand une petite fonction n’est utile qu’à l’intérieur d’une autre, et
ne doit pas être visible ni utilisable depuis l’extérieur.
SOUMBOU IYO GILBERT JUDE GI1/B ECES
9.2. Imbrication à 2 def, en profondeur (une fonction dans une
fonction dans une fonction)
def niveau1():
print("Entrée niveau 1")
def niveau2():
print("Entrée niveau 2")
niveau2()
print("Sortie niveau 1")
niveau1()
# Entrée niveau 1
# Entrée niveau 2
# Sortie niveau 1
Quand l’utiliser : pour organiser un traitement en étapes bien séparées, chacune
cachée dans la précédente.
9.3. Imbrication à 2 def, en largeur (deux sous-fonctions
indépendantes côte à côte)
def programme_principal():
def sous_fonction_1():
print("Sous-fonction 1")
def sous_fonction_2():
print("Sous-fonction 2")
sous_fonction_1()
sous_fonction_2()
programme_principal()
# Sous-fonction 1
# Sous-fonction 2
Quand l’utiliser : quand une fonction principale doit accomplir deux tâches distinctes,
chacune confiée à sa propre sous-fonction interne.
9.4. Imbrication à 3 def, en profondeur (trois niveaux empilés)
def niveau1():
print("Niveau 1")
def niveau2():
print("Niveau 2")
def niveau3():
print("Niveau 3")
niveau3()
niveau2()
niveau1()
# Niveau 1
# Niveau 2
# Niveau 3
SOUMBOU IYO GILBERT JUDE GI1/B ECES
Quand l’utiliser : rarement au-delà de 2 ou 3 niveaux — trop de profondeur rend le
code difficile à lire. Utile quand chaque niveau a besoin d’accéder aux variables du
niveau juste au-dessus (voir les closures, exercices 214-215 du fichier d’exercices).
9.5. Imbrication à 3 def, en largeur (exemple concret : gestion d’une
commande)
def gestion_commande():
def verifier_stock(article):
return article in ["pomme", "banane"]
def calculer_prix(article, quantite):
prix_unitaire = 2 if article == "pomme" else 1
return prix_unitaire * quantite
def confirmer_commande(article, quantite):
if verifier_stock(article):
total = calculer_prix(article, quantite)
print(f"Commande confirmée : {quantite} {article}(s) pour {total}€")
else:
print("Article indisponible")
confirmer_commande("pomme", 3)
gestion_commande()
# Commande confirmée : 3 pomme(s) pour 6€
Ce que cet exemple montre : trois sous-fonctions (verifier_stock, calculer_prix,
confirmer_commande) travaillent ensemble à l’intérieur d’une seule fonction principale
— chacune s’occupe d’une tâche précise, et confirmer_commande appelle les deux
autres.
9.6. Pourquoi imbriquer des fonctions ?
Pour cacher les détails internes d’un traitement : les sous-fonctions ne sont pas
visibles ni utilisables depuis l’extérieur de la fonction principale.
Pour organiser un traitement complexe en petites étapes claires et nommées.
Pour créer des closures (fonctions qui « retiennent » une valeur, voir exercices
214-215).
⚠ Attention : au-delà de 2 ou 3 niveaux d’imbrication, le code devient difficile à lire. Il
vaut souvent mieux définir des fonctions séparées au niveau du programme principal
plutôt que de trop imbriquer.
9.7. Tableau récapitulatif
Nombre de def
Organisation possible Exemple d’usage typique
imbriquées
une fonction contient une sous-
1 cacher un calcul intermédiaire
fonction
en profondeur (A contient B) ou en
2 validation puis traitement
largeur (2 sous-fonctions côte à côte)
en profondeur (A contient B contient
vérifier + calculer + confirmer
3 C) ou en largeur (3 sous-fonctions
(gestion de commande)
côte à côte)
SOUMBOU IYO GILBERT JUDE GI1/B ECES
10. Résumé à retenir
def permet de créer une fonction (un sous-programme) ; le programme
principal est le code exécuté en dehors de toute fonction.
Une fonction peut avoir des paramètres positionnels, nommés, à valeur par défaut,
*args ou **kwargs — et même tous à la fois, dans cet ordre précis.
On peut appeler une fonction de nombreuses façons : positionnelle, nommée, avec
déballage */**, en chaîne, dans une boucle…
return arrête toute la fonction (y compris toutes ses boucles internes) et peut
renvoyer une, plusieurs, ou aucune valeur.
break n’arrête que la boucle la plus proche ; pour sortir de plusieurs boucles
imbriquées dans une fonction, return est le moyen le plus simple.
Une fonction peut combiner librement des boucles for et while, imbriquées dans
n’importe quel ordre, selon que le nombre d’itérations est connu à l’avance (for)
ou dépend d’une condition (while).
SOUMBOU IYO GILBERT JUDE GI1/B ECES