Vue d'ensemble
Une fonction range un morceau de code sous un nom, pour le réutiliser autant de
fois qu'on veut sans le réécrire. Elle prend des paramètres (ses entrées) et peut
renvoyer une valeur (sa sortie) grâce à return. C'est la brique de base
de tout programme propre : au lieu d'un long script illisible, on découpe le travail en petites
fonctions qui s'appellent les unes les autres.
Bien distinguer return (renvoyer une valeur réutilisable) de print
(afficher à l'écran) est LE point qui débloque la programmation propre — et qui piège la majorité
des élèves à l'entrée en prépa. On y ajoute deux notions clés du programme de Sup : le
renvoi de plusieurs valeurs et la portée des variables.
return avec print,
savoir renvoyer plusieurs valeurs et comprendre la portée locale des variables.
Prérequis
- Variables, types et expressions
- Conditions (
if / else) et boucles (pour le corps des fonctions) - Le tuple et le dépaquetage
x, y = ...(revu ici en contexte)
Tu confonds encore return et print ? C'est l'erreur la
plus fréquente en début de prépa, et elle fausse tout un DS d'informatique. Nos mentors alumni
X · Centrale · Mines te font passer le cap une bonne fois pour toutes, sur tes propres exercices.
1. Définir et appeler une fonction
def nom(paramètres): définit une fonction. Les lignes indentées en dessous forment son
corps. Le mot-clé return renvoie une valeur à l'endroit de
l'appel. Écrire nom(arguments) exécute le corps puis remplace l'appel
par la valeur renvoyée.
def carre(x):
return x * x
y = carre(5) # y reçoit 25
print(carre(3)) # affiche 9def carre(x):Définition. On crée une fonction nommée carre avec un paramètre x (son entrée). Les deux-points annoncent le corps indenté. Ce corps n'est PAS exécuté tout de suite : il attend un appel. return x * xCorps + valeur de retour. Quand la fonction est appelée, elle calcule x * x et renvoie ce résultat. return termine aussi immédiatement la fonction.y = carre(5)Appel. On exécute carre avec x = 5 ; l'appel « vaut » 25, donc y reçoit 25. Ici 5 est l'argument (la valeur concrète) qui vient remplir le paramètre x.print(carre(3))Appel + affichage. carre(3) vaut 9, qu'on passe à print : affiche 9 à l'écran.x) ; l'argument est la valeur passée lors de l'appel
(5, 3). Le paramètre est une boîte, l'argument est ce qu'on met dedans.
2. return n'est pas print
return renvoie une valeur qu'on peut réutiliser : la ranger dans une
variable, la recalculer, la passer à une autre fonction… print ne fait
qu'afficher du texte à l'écran ; il ne renvoie rien d'exploitable. C'est LE piège
numéro un du début de prépa.
def double_print(x):
print(x * 2) # affiche seulement
def double_return(x):
return x * 2 # renvoie une valeur réutilisable
a = double_print(3) # affiche 6, mais a vaut None
b = double_return(3) # b vaut 6 (rien n'est affiché)
print(b + 1) # affiche 7a = double_print(3)Piège. double_print affiche 6 mais ne renvoie rien : par défaut une fonction renvoie None. Donc a vaut None — inexploitable.b = double_return(3)Le bon réflexe. double_return renvoie 6 sans rien afficher. b vaut 6 et on peut le réutiliser : b + 1 donne 7.print(b + 1)Réutilisation. Parce que double_return a renvoyé une vraie valeur, on peut calculer avec : impossible de faire ça avec le résultat de double_print.| Instruction | Ce qui s'affiche | Valeur récupérée |
|---|---|---|
a = double_print(3) | 6 | a = None |
b = double_return(3) | (rien) | b = 6 |
return renvoie None. Si tu écris
print(...) dans une fonction là où il fallait return ..., tu ne pourras pas
réutiliser le résultat : toute tentative de réutilisation donnera None. Règle simple :
une fonction de calcul se termine par return, pas par print.
3. Plusieurs paramètres et arguments
Une fonction peut avoir plusieurs paramètres, séparés par des virgules. À l'appel, les arguments sont associés aux paramètres dans l'ordre (arguments positionnels) : le premier argument remplit le premier paramètre, et ainsi de suite.
def puissance(base, exposant):
return base ** exposant
print(puissance(2, 10)) # 2 ** 10 = 1024
print(puissance(10, 2)) # 10 ** 2 = 100def puissance(base, exposant):Deux paramètres. base reçoit le premier argument, exposant le second.puissance(2, 10)L'ordre compte. base = 2, exposant = 10 → 1024.puissance(10, 2)Inversé, résultat différent. base = 10, exposant = 2 → 100. Mélanger l'ordre change tout.puissance(2, 10) et puissance(10, 2) ne renvoient pas la même chose. Range
tes arguments dans le même ordre que les paramètres de la définition.
Arguments par défaut
On peut donner à un paramètre une valeur par défaut : si l'appel ne fournit pas d'argument pour lui, Python utilise la valeur par défaut. Pratique pour rendre un paramètre optionnel.
def salut(nom, poli=True):
if poli:
return "Bonjour " + nom
else:
return "Salut " + nom
print(salut("Ada")) # Bonjour Ada
print(salut("Ada", False)) # Salut Adadef salut(nom, poli=True):Valeur par défaut. poli vaut True si on ne précise rien. nom reste obligatoire.salut("Ada")Sans le second argument. poli prend sa valeur par défaut True → « Bonjour Ada ».salut("Ada", False)On surcharge le défaut. On fournit False pour poli → « Salut Ada ».poli=True) doit se placer après les paramètres
obligatoires (nom). Sinon Python refuse la définition.
4. Renvoyer plusieurs valeurs
Une fonction peut renvoyer plusieurs valeurs d'un coup en les séparant par des
virgules après return. Python les regroupe alors dans un tuple (une
liste figée de valeurs). Côté appelant, on récupère chaque valeur avec le
dépaquetage x, y = ....
def divise(a, b):
quotient = a // b
reste = a % b
return quotient, reste # renvoie un tuple (q, r)
q, r = divise(17, 5) # dépaquetage : q = 3, r = 2
print(q) # 3
print(r) # 2 return quotient, resteTuple de retour. La virgule regroupe les deux valeurs. La fonction renvoie en réalité UNE valeur, le tuple (3, 2).q, r = divise(17, 5)Dépaquetage. À gauche, deux noms pour deux valeurs : q reçoit le premier élément du tuple (3), r le second (2). Le nombre de noms doit correspondre au nombre de valeurs renvoyées.print(q)Chaque valeur est utilisable. q et r sont deux variables ordinaires, exploitables séparément.resultat = divise(17, 5) range le
tuple entier dans resultat ; on accède alors aux valeurs par index :
resultat[0] vaut 3, resultat[1] vaut 2.
5. Portée : variables locales et globales
Une variable créée dans une fonction est locale : elle n'existe que pendant l'exécution de la fonction et disparaît ensuite. Elle est invisible à l'extérieur. Les paramètres, eux aussi, sont des variables locales.
def f():
n = 10 # n est locale à f
return n
print(f()) # affiche 10
# print(n) # -> erreur : n n'existe pas en dehors de f n = 10Variable locale. n naît dans f et n'existe que le temps de l'appel.print(f())On récupère la valeur, pas la variable. f() renvoie 10 ; c'est ce nombre qu'on affiche, pas la variable n elle-même.# print(n)Erreur si on l'active. En dehors de f, n n'existe pas : Python lèverait NameError. Pour sortir une valeur d'une fonction, on la return.À l'inverse, une variable définie hors de toute fonction est globale et peut être lue depuis une fonction. Mais s'appuyer là-dessus rend le code fragile et difficile à relire.
seuil = 10 # variable globale
def au_dessus(x):
return x > seuil # lit la globale seuil
print(au_dessus(15)) # Truereturn. Évite
de dépendre de variables globales : la version au_dessus(x, seuil) est plus claire et
réutilisable que celle qui va « pêcher » seuil à l'extérieur.
Portée, tuples, valeurs par défaut : ça se joue en manipulant. En stage intensif Majorant, tu écris et déboguff tes propres fonctions avec un alumni X · Centrale · Mines qui repère tout de suite tes réflexes fragiles avant qu'ils ne coûtent des points en concours.
Découvrir les stages →6. Composer des fonctions
La grande force des fonctions : une fonction peut en appeler une autre. On construit ainsi des programmes en assemblant des briques testées séparément. On écrit une petite fonction utile, puis on la réutilise partout.
def est_pair(n):
return n % 2 == 0
def compte_pairs(debut, fin):
total = 0
for k in range(debut, fin + 1):
if est_pair(k): # on réutilise est_pair
total = total + 1
return total
print(compte_pairs(1, 10)) # 5 (2, 4, 6, 8, 10)def est_pair(n):Brique de base. n % 2 == 0 vaut True si n est pair. La fonction renvoie ce booléen. if est_pair(k):Réutilisation. Dans compte_pairs, on appelle est_pair au lieu de réécrire le test. Le code reste lisible et on ne duplique rien. total = total + 1Compteur. On incrémente à chaque k pair rencontré dans l'intervalle. return totalRésultat. Le return est bien APRÈS la boucle, une fois tout compté. De 1 à 10, il y a 5 nombres pairs.7. Exercices d'application
À faire de tête (ou au brouillon) avant d'ouvrir le corrigé.
Écris une fonction est_pair(n) qui renvoie True si n est pair, False sinon.
Voir la correction détaillée
n % 2 == 0. Cette comparaison vaut déjà True ou False, donc on la renvoie directement.def est_pair(n):
return n % 2 == 0est_pair(4) renvoie True, est_pair(7) renvoie False. On utilise bien return (et non print) pour pouvoir réutiliser le booléen dans un if.Écris une fonction division(a, b) qui renvoie le couple (quotient, reste) de la division entière de a par b. Montre comment récupérer les deux valeurs.
Voir la correction détaillée
// et le reste avec %. On renvoie les deux séparés par une virgule : Python en fait un tuple.def division(a, b):
return a // b, a % b
q, r = division(17, 5) # dépaquetage : q = 3, r = 2
print(q, r) # affiche 3 2q, r = division(17, 5) : q reçoit 3 et r reçoit 2, chacune réutilisable séparément.Qu'affiche exactement ce programme ? Et que vaut r à la fin ?
def montre(x):
print(x + 1)
def calcule(x):
return x + 1
a = montre(4)
r = calcule(4)
print(r + 10)Voir la correction détaillée
a = montre(4) : montre exécute print(4 + 1) donc affiche 5. Mais montre ne fait pas de return : elle renvoie None, donc a vaut None.r = calcule(4) : calcule renvoie 4 + 1 = 5 sans rien afficher. Donc r vaut 5.print(r + 10) affiche 5 + 10 = 15. Bilan à l'écran : 5 puis 15. Seul calcule, grâce à return, fournit une valeur réutilisable.8. Erreurs classiques (les pièges qui coûtent des points)
Voici les fautes qu'on retrouve dans presque toutes les copies de début de prépa. Les connaître, c'est déjà les éviter.
return → la fonction renvoie None. Une fonction
qui calcule mais ne fait pas return renvoie None par défaut.
x = ma_fonction(...) donne alors x = None, et tout calcul ensuite plante ou
donne n'importe quoi.
print au lieu de return. Afficher n'est pas
renvoyer. Une fonction qui fait seulement print(resultat) ne permet pas de réutiliser la
valeur : impossible de la ranger dans une variable ou de la passer à une autre fonction.
NameError. Pour la faire
sortir, il faut la return.
return dans une boucle qui coupe trop tôt. return
termine TOUTE la fonction, pas seulement l'itération. Si tu écris return dès la première
itération d'un compteur, tu sors avant d'avoir tout parcouru. Le return d'un total va
APRÈS la boucle.
divise(17, 5) ne
« garde » rien tout seul : la valeur renvoyée est perdue si tu ne l'affectes pas à une variable
(q, r = divise(17, 5)). Un appel dont on ignore le retour ne sert à rien pour la suite.
8. Pour aller plus loin
Les fonctions sont partout : dès que tu manipules des listes, que tu écris un algorithme de recherche ou une fonction qui s'appelle elle-même, tu réinvestis tout ce chapitre. Enchaîne avec :
- Récursivité — une fonction qui s'appelle elle-même, cas de base et return
- Listes — parcourir, construire et renvoyer des listes depuis une fonction
- Recherche dichotomique — un algorithme classique écrit comme une fonction à paramètres
Récap final — Ce qu'il faut absolument retenir
Tu dois pouvoir répondre « oui » sans hésiter à chaque point.
- Sais-tu définir une fonction avec
def, des paramètres et unreturn? - Sais-tu qu'un appel
f(...)« vaut » la valeur renvoyée et peut être rangé dans une variable ? - Sais-tu distinguer un paramètre (dans la définition) d'un argument (à l'appel) ?
- Sais-tu que
returnrenvoie (réutilisable) alors queprintne fait qu'afficher ? - Sais-tu qu'une fonction sans
returnrenvoieNone? - Sais-tu que l'ordre des arguments positionnels change le résultat ?
- Sais-tu donner une valeur par défaut à un paramètre (
poli=True) et l'appeler avec ou sans ? - Sais-tu renvoyer plusieurs valeurs avec
return a, b(un tuple) ? - Sais-tu récupérer ces valeurs par dépaquetage
x, y = f(...)? - Sais-tu qu'une variable créée dans une fonction est locale (invisible dehors) ?
- Sais-tu qu'il vaut mieux communiquer par paramètres et retour plutôt que par variables globales ?
- Sais-tu appeler une fonction depuis une autre pour réutiliser tes briques ?