Les fonctions
Découper un programme en outils réutilisables : def, paramètres, return, et la portée des variables
§1.Tu en utilises depuis le premier chapitre
print(), input(), len(), range(), sorted() — ce sont toutes des FONCTIONS. Quelqu'un a écrit le code compliqué une fois, l'a rangé sous un nom simple, et depuis, le monde entier l'utilise sans savoir comment il marche.
Écrire tes propres fonctions, c'est passer du côté de celui qui fabrique les outils. C'est probablement la compétence qui sépare le plus nettement le débutant du programmeur.
L'intérêt n'est pas seulement d'éviter de se répéter. C'est de pouvoir raisonner sur un morceau de programme ISOLÉMENT : une fonction bien écrite se comprend, se teste et se corrige sans avoir le reste en tête.
def saluer(): print("Bonjour !") print("Comment vas-tu ?") # Ici, rien ne s'est encore affiché.saluer()saluer()DÉFINIR une fonction avec def, c'est écrire le mode d'emploi : rien ne s'exécute. C'est l'APPEL — le nom suivi de parenthèses — qui déclenche le travail. Et il faut définir avant d'appeler.
§3.Anatomie
- def nom(parametres):
- Le mot-clé def, un nom de ton choix, les paramètres entre parenthèses, puis deux-points. Le corps est indenté en dessous, comme pour un if.
- Paramètre et argument
- Le PARAMÈTRE est le nom écrit dans la définition ; l'ARGUMENT est la valeur réellement passée à l'appel. On confond souvent les deux, sans grande conséquence.
- Exemple. def carre(n) — n est un paramètre. carre(5) — 5 est un argument.
- return
- Renvoie une valeur à celui qui a appelé, et termine immédiatement la fonction. Sans return, la fonction renvoie None.
§4.La distinction qui compte : afficher ou renvoyer
C'est LE point de bascule du chapitre, et la source d'erreur numéro un dans les exercices.
print() envoie du texte à l'écran, pour un humain. Le programme, lui, n'en récupère rien. return donne une VALEUR au programme, qui peut la stocker, la calculer, la comparer — mais rien ne s'affiche.
Une fonction qui affiche au lieu de renvoyer est un cul-de-sac : on ne peut rien faire de son travail.
def carre_affiche(n): print(n * n) def carre_renvoie(n): return n * n carre_affiche(5)resultat = carre_renvoie(5)print(resultat + 1) perdu = carre_affiche(5)print(perdu)carre_renvoie permet de continuer à calculer. carre_affiche, non : sa valeur de retour est None, parce qu'elle n'a pas de return. Retiens la règle : une fonction CALCULE et renvoie ; c'est l'appelant qui décide d'afficher.
def moyenne(notes, arrondi=2): if len(notes) == 0: return 0 return round(sum(notes) / len(notes), arrondi) print(moyenne([12, 15, 9]))print(moyenne([12, 15, 9], 0))print(moyenne([12, 15, 9], arrondi=4))Un paramètre avec une valeur PAR DÉFAUT devient facultatif. On peut aussi nommer les arguments à l'appel (arrondi=4), ce qui rend le code bien plus lisible quand une fonction en prend plusieurs.
def contient_negatif(liste): for x in liste: if x < 0: return True # on sait déjà : inutile de continuer return False # on n'a rien trouvé def somme_positifs(liste): total = 0 for x in liste: if x > 0: total = total + x return total # APRÈS la boucle, pas dedans print(contient_negatif([1, -2, 3]))print(contient_negatif([1, 2, 3]))print(somme_positifs([1, -2, 3]))§10.La portée des variables
Une variable créée DANS une fonction n'existe que pendant son exécution. À l'extérieur, elle est inconnue : c'est une variable LOCALE.
Cette étanchéité est une protection, pas une contrainte. Elle garantit qu'une fonction ne peut pas casser accidentellement le reste du programme — et c'est justement ce qui permet de raisonner sur elle isolément.
Une fonction peut LIRE une variable définie à l'extérieur, mais si elle lui affecte une valeur, Python en crée une nouvelle, locale, sans toucher à l'originale.
compteur = 0 def incremente(): compteur = 100 # crée une variable LOCALE return compteur print(incremente())print(compteur) # l'originale n'a pas bougéPlutôt que de chercher à modifier des variables extérieures — ce qui rend un programme imprévisible — passe les valeurs en PARAMÈTRES et récupère le résultat avec return. C'est la bonne façon de faire circuler l'information.
def est_pair(n): return n % 2 == 0 def pairs_de(liste): return [x for x in liste if est_pair(x)] def resume(liste): p = pairs_de(liste) return len(p), sum(p) nombre, total = resume([1, 2, 3, 4, 5, 6])print(nombre, total)Une fonction peut en appeler d'autres — c'est même le but. Remarque aussi qu'on peut renvoyer PLUSIEURS valeurs d'un coup, séparées par des virgules, et les récupérer en une ligne.
§13.Ce qui fait une bonne fonction
- Un nom qui dit ce qu'elle fait
- calculer_moyenne() est bon, truc() est inutile. Un verbe à l'infinitif pour une action, une question pour un booléen : est_premier(), contient_negatif().
- Une seule responsabilité
- Si tu dois écrire « et » pour décrire ce que fait ta fonction, elle en fait probablement trop. Découpe.
- Courte
- Au-delà d'une vingtaine de lignes, on ne la tient plus en tête. Ce n'est pas une règle absolue, mais un signal.
- Le principe DRY
- Don't Repeat Yourself. Si tu copies-colles un bloc pour la deuxième fois, c'est le moment d'en faire une fonction — sinon la troisième correction de bug devra être faite à trois endroits.
def pgcd(a, b): """Renvoie le plus grand commun diviseur de a et b. Utilise l'algorithme d'Euclide : tant que b n'est pas nul, on remplace (a, b) par (b, a % b). """ while b != 0: a, b = b, a % b return a print(pgcd(12, 18))Une chaîne placée juste après la ligne def devient la DOCSTRING de la fonction. Ce n'est pas un commentaire ordinaire : sur un Python installé, l'interpréteur la garde en mémoire — help(pgcd) l'affiche, et les outils de documentation la lisent. C'est la convention pour expliquer ce qu'une fonction attend et ce qu'elle renvoie.
Le même travail, mais réparti en fonctions qui se comprennent chacune isolément.
À retenir
- def définit, nom() appelle. Il faut définir avant d'appeler.
- print AFFICHE pour un humain ; return DONNE une valeur au programme. Une fonction calcule et renvoie.
- Sans return, une fonction renvoie None — d'où les « None » inattendus.
- return arrête la fonction immédiatement : place-le après la boucle si tu accumules.
- Les paramètres peuvent avoir une valeur par défaut, et les arguments peuvent être nommés à l'appel.
- Une variable créée dans une fonction est LOCALE ; fais circuler l'information par paramètres et return.
- On peut renvoyer plusieurs valeurs : return a, b puis x, y = f().
- Un bon nom, une seule responsabilité, une docstring — et jamais deux fois le même bloc de code.