Définir des fonctions
Créez des blocs de code réutilisables avec def, les paramètres et les valeurs de retour.
- Définir et appeler des fonctions avec def
- Utiliser des paramètres positionnels, nommés et par défaut
- Renvoyer des valeurs depuis les fonctions
- Écrire des docstrings pour documenter les fonctions
De la formule à la machine nommée
Les mathématiques abhorrent la répétition. Vous avez appris comme une règle, une définition, employée mille fois, sur mille entrées différentes :
Le def de Python est le même geste : lier un nom à un calcul, pour que n’importe quel appelant puisse l’appliquer. La fonction est une machine avec des fentes d’entrée étiquetées et une porte de sortie :
def add(a, b):
return a + b
result = add(3, 5) # 8Le nom, les parenthèses tenant les paramètres , les deux points qui amorcent la recette, voilà la définition. L’appel add(3, 5) consiste à appliquer la règle en , , exactement comme applique une règle en .
Définir et appeler
La première fonction que vous écrivez change le monde un salut à la fois :
def greet(name):
"""Print a greeting for the given name."""
print(f"Hello, {name}!")
greet("Alice") # Hello, Alice!Trois parties méritent un nom. Les paramètres sont les variables de la définition, les fentes d’entrée . Les arguments sont les valeurs concrètes fournies au site d’appel, l’entrée . Et la ligne entre triples guillemets à l’intérieur est la docstring : de la documentation vivant à côté du code, pour que help(greet) puisse répondre ce que fait la fonction.
Return : la porte de sortie
print envoie du texte à l’écran ; return rend une valeur à l’appelant. La distinction est subtile et décisive :
def add(a, b):
return a + b
result = add(3, 5) # result == 8
printed = print("8") # printed est None — print ne renvoie rienUne fonction sans return renvoie silencieusement None, la machine ne produit aucune sortie. Quand vous voulez que le résultat arithmétique de votre fonction continue de circuler, souvenez-vous : return, pas print.
Paramètres par défaut
Certains paramètres ont un réglage naturel que la plupart des appels garderont. Donnez-leur une valeur par défaut, et les appelants pourront la remplacer :
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Alice")) # Hello, Alice!
print(greet("Bob", "Hey")) # Hey, Bob!La règle d’ordre est rigide : les paramètres par défaut viennent après les autres. def f(x, y=5) est légal ; def f(x=1, y) est une erreur de syntaxe, car Python résout les arguments par position depuis la gauche et un trou serait ambigu.
Arguments nommés
Les arguments peuvent aussi arriver nommés, ce qui achète de la clarté quand l’ensemble des paramètres grandit :
def create_user(name, age, role="student"):
return {"name": name, "age": age, "role": role}
user = create_user(age=25, name="Alice", role="admin")Les arguments nommés peuvent venir dans n’importe quel ordre, le nom du paramètre est l’étiquette de chaque paquet. Un appel qui nomme ses entrées se lit comme une phrase au lieu d’un code à décoder.
*args et **kwargs
Et si le nombre d’entrées est inconnu d’avance ? Une somme ne sait pas combien de termes elle recevra. *args recueille tout nombre d’arguments positionnels dans un tuple ; **kwargs recueille les arguments nommés dans un dict :
def total(*args):
return sum(args)
print(total(1, 2, 3, 4)) # 10
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25)L’étoile est le geste : * déplie la liste d’arguments en un faisceau. C’est la différence entre une somme à signature fixe et une somme qui accepte pour tout .
Le retour anticipé comme garde
Certains codes commencent par vérifier l’unique cas qui ne doit pas aller plus loin. Les raisonnements de la forme « sauf si » s’énoncent comme une garde en haut, rendant immédiatement :
def divide(a, b):
if b == 0:
return None
return a / bUne clause de garde aplatit une paire if/else en ligne droite : le cas d’échec sort tôt et le chemin honnête s’exécute sans imbrication.
Un exemple travaillé : la machine f
La quadratique qui a ouvert la leçon devient trois instructions return :
def quad(x):
"""Renvoie x² − 5x + 6."""
return x * x - 5 * x + 6
quad(2) # 0
quad(3) # 0
quad(1) # 2La même règle, trois entrées. La formule devient une machine réutilisable : on la définit une fois, on l’applique mille fois, et la docstring laisse écrit quelle règle elle enferme.
Pièges courants
- Arguments par défaut mutables.
def f(items=[])crée une liste partagée entre tous les appels, les éléments s’empilent d’un appel à l’autre. MettezNonepar défaut et construisez la liste à l’intérieur. - Oublier
return. Une fonction sans retour rendNone; vous demandiez une valeur et avez reçu une ombre. - Trop de paramètres. Passé trois ou quatre, les fentes deviennent un casse-tête. Regroupez les arguments affines dans un dict ou un dataclass.
- Appeler une fonction définie plus bas. Python exécute de haut en bas ; appeler
f()avant que ledef fn’atteigne l’interpréteur lève uneNameError. Définissez avant d’appeler.
🧩 Défis
🧩 Défi, réfléchissez d'abord, puis révélez
Écrivez is_palindrome(text) qui renvoie True quand la chaîne se lit pareil dans les deux sens ; ignorez la casse.
💡 Réponse : def is_palindrome(text): return text.lower() == text.lower()[::-1], la mise en minuscules symétrise la comparaison, et la tranche inversée [::-1] est l'image miroir.
🧩 Défi, réfléchissez d'abord, puis révélez
Écrivez fizzbuzz(n) qui renvoie une liste de 1 à , remplaçant les multiples de 3 par "Fizz", les multiples de 5 par "Buzz" et les multiples des deux par "FizzBuzz".
💡 Réponse : Les multiples des deux sont des multiples de $\mathrm{lcm}(3,5) = 15$, alors testez ce cas d'abord : ["FizzBuzz" if i % 15 == 0 else "Fizz" if i % 3 == 0 else "Buzz" if i % 5 == 0 else i for i in range(1, n+1)].
🤔 Questions socratiques
- Pourquoi les paramètres par défaut doivent-ils suivre les autres ? Que se casserait-il si la règle était inversée ?
- Que vous donne
*argsqu’un unique paramètre liste ne donne pas ? Quand préférez-vous l’un à l’autre ? - Comment Python décide-t-il quelle définition appliquer quand coexistent
def f(x)etdef f(x, y=5)?
✅ Vérification rapide
1. Que renvoie ceci ? def f(x, y=3): return x + y; f(5)
2. Quelle est la sortie ? def f(a, b=[]): b.append(a); return b; print(f(1)); print(f(2))