19. Définir et appeler des fonctions
19.1) Ce que sont les fonctions et pourquoi elles comptent
Une fonction(function) est un bloc de code nommé qui exécute une tâche spécifique. Vous utilisez déjà des fonctions tout au long de ce livre—print(), input(), len(), type(), et bien d’autres. Ce sont des fonctions intégrées que Python fournit. Maintenant, vous allez apprendre à créer vos propres fonctions personnalisées pour organiser votre code et le rendre réutilisable.
Pourquoi les fonctions comptent
Les fonctions sont fondamentales pour écrire des programmes clairs et faciles à maintenir. Elles offrent plusieurs avantages essentiels :
1. Réutilisabilité du code
Sans fonctions, vous devriez copier-coller le même code à chaque fois que vous voulez effectuer une tâche. Prenons le calcul de l’aire d’un rectangle à plusieurs endroits :
# Sans fonctions - code répétitif
length1 = 5
width1 = 3
area1 = length1 * width1
print(f"Area 1: {area1}")
length2 = 8
width2 = 4
area2 = length2 * width2
print(f"Area 2: {area2}")
length3 = 10
width3 = 6
area3 = length3 * width3
print(f"Area 3: {area3}")Output:
Area 1: 15
Area 2: 32
Area 3: 60Cette répétition est fastidieuse et sujette aux erreurs. Si vous devez changer la façon dont vous calculez l’aire (peut-être pour inclure des unités ou un arrondi), vous devriez mettre à jour chaque emplacement. Les fonctions résolvent ce problème en vous permettant d’écrire le code une seule fois et de l’utiliser de nombreuses fois.
2. Organisation du code
Les fonctions découpent les grands programmes en morceaux plus petits et gérables. Chaque fonction gère une tâche spécifique, rendant votre code plus facile à comprendre et à maintenir. Au lieu d’un long script avec des centaines de lignes, vous pouvez organiser les opérations liées dans des fonctions nommées qui communiquent clairement leur objectif.
3. Abstraction
Les fonctions cachent les détails d’implémentation derrière une interface simple. Quand vous appelez len(my_list), vous n’avez pas besoin de savoir comment Python compte les éléments—vous obtenez simplement le résultat. De la même manière, vos fonctions peuvent fournir des interfaces simples à des opérations complexes, rendant votre code plus facile à utiliser et à comprendre.
4. Tests et débogage(debugging)
Les fonctions facilitent le test de morceaux individuels de votre programme. Vous pouvez vérifier que chaque fonction fonctionne correctement de manière isolée avant de les combiner dans un programme plus grand. Quand quelque chose se passe mal, les fonctions vous aident à réduire l’endroit où le problème se produit.
Tout au long du reste de ce chapitre, vous apprendrez à définir vos propres fonctions, à leur transmettre des informations, à récupérer des résultats, et à les documenter clairement. Ces compétences sont essentielles pour écrire du code Python professionnel.
19.2) Définir des fonctions avec def
Pour créer une fonction en Python, vous utilisez le mot-clé def (abréviation de « define »). La structure de base d’une définition de fonction ressemble à ceci :
def function_name():
# Bloc de code qui s'exécute quand la fonction est appelée
statement1
statement2
# ... plus d'instructionsDécomposons chaque partie :
def: le mot-clé qui indique à Python que vous définissez une fonctionfunction_name: le nom que vous choisissez pour votre fonction (suit les mêmes règles que les noms de variables)(): des parenthèses qui contiendront plus tard des paramètres (nous les verrons dans la section suivante):: deux-points qui marque la fin de l’en-tête de la fonction- Bloc de code indenté : les instructions qui composent le corps de la fonction (doit être indenté)
Votre première fonction
Voici une fonction simple qui affiche un message de bienvenue :
def greet():
print("Hello!")
print("Welcome to Python functions.")
# Appeler la fonction
greet()Output:
Hello!
Welcome to Python functions.Quand vous définissez une fonction, Python s’en souvient mais n’exécute pas immédiatement le code à l’intérieur. Le code ne s’exécute que lorsque vous appelez la fonction en écrivant son nom suivi de parenthèses : greet().
Conventions de nommage des fonctions
Les noms de fonctions suivent les mêmes règles que les noms de variables (comme nous l’avons appris au Chapitre 3) :
- Utilisez des lettres minuscules
- Séparez les mots avec des underscores (snake_case)
- Commencez par une lettre ou un underscore, pas par un chiffre
- Utilisez des noms descriptifs qui indiquent ce que fait la fonction
# Bons noms de fonctions
def calculate_total():
pass
def get_user_age():
pass
def display_menu():
pass
# Mauvais noms de fonctions (mais syntaxiquement valides)
def x(): # Pas descriptif
pass
def CalculateTotal(): # Devrait utiliser des minuscules
pass
def calc(): # Trop abrégé
passNote : Nous utilisons pass ici comme espace réservé (comme nous l’avons appris au Chapitre 8). Il ne fait rien mais permet à la définition de la fonction d’être syntaxiquement complète.
Les fonctions peuvent contenir n’importe quel code
Le corps d’une fonction peut contenir n’importe quelles instructions Python que vous avez apprises jusqu’ici : affectations de variables, conditions, boucles(loop), et même des appels à d’autres fonctions.
def check_temperature():
temperature = 72
if temperature > 75:
print("It's warm.")
elif temperature > 60:
print("It's comfortable.")
else:
print("It's cool.")
check_temperature()Output:
It's comfortable.Plusieurs définitions de fonctions
Vous pouvez définir autant de fonctions que nécessaire dans votre programme. Chaque fonction est indépendante et peut être appelée séparément :
def morning_greeting():
print("Good morning!")
def evening_greeting():
print("Good evening!")
# Appeler chaque fonction
morning_greeting()
evening_greeting()Output:
Good morning!
Good evening!Ordre de définition des fonctions
En Python, vous devez définir une fonction avant de l’appeler. L’interpréteur Python lit votre code de haut en bas, donc si vous essayez d’appeler une fonction avant de la définir, vous obtiendrez une erreur :
# WARNING: This will cause a NameError - for demonstration only
# PROBLEM: Function called before it's defined
say_hello() # NameError: name 'say_hello' is not defined
def say_hello():
print("Hello!")L’ordre correct est de définir d’abord, puis d’appeler :
# Correct: Define first
def say_hello():
print("Hello!")
# Then call
say_hello()Output:
Hello!Cependant, les fonctions peuvent appeler d’autres fonctions qui sont définies plus loin dans le fichier, tant que ces appels se produisent après toutes les définitions :
def first_function():
print("First function")
second_function() # Ceci est correct - appelé à l'exécution
def second_function():
print("Second function")
# Les deux fonctions sont définies avant que nous appelions la première
first_function()Output:
First function
Second functionLes fonctions créent une portée locale
Les variables créées à l’intérieur d’une fonction n’existent qu’à l’intérieur de cette fonction. Cela s’appelle la portée locale(local scope) (nous l’explorerons en détail au Chapitre 21). Pour l’instant, comprenez que ce qui se passe à l’intérieur d’une fonction reste à l’intérieur de la fonction :
def create_message():
message = "This is local"
print(message)
create_message()
# Cela provoquerait une erreur :
# print(message) # NameError: name 'message' is not definedOutput:
This is localLa variable message n’existe que pendant l’exécution de la fonction. Une fois la fonction terminée, la variable disparaît.
Fonctions vides avec pass
Parfois, vous voulez définir la structure d’une fonction mais l’implémenter plus tard. Utilisez pass comme espace réservé :
def future_feature():
pass # TODO: Implémenter ceci plus tard
# La fonction existe et peut être appelée, mais ne fait rien
future_feature() # S'exécute sans erreur, ne fait rienC’est utile lorsque vous esquissez la structure de votre programme avant de remplir les détails.
19.3) Appeler des fonctions et passer des arguments
Définir une fonction crée un morceau de code réutilisable, mais pour rendre les fonctions vraiment puissantes, vous devez leur transmettre des informations. Ces informations sont transmises via des arguments(arguments).
Paramètres vs arguments
Avant de continuer, clarifions deux termes souvent confondus :
- Paramètre(parameter) : un nom de variable dans la définition de la fonction qui recevra une valeur
- Argument(argument) : la valeur réelle que vous passez à la fonction lorsque vous l’appelez
def greet(name): # 'name' est un paramètre
print(f"Hello, {name}!")
greet("Alice") # "Alice" est un argumentOutput:
Hello, Alice!Considérez les paramètres comme des espaces réservés et les arguments comme les données réelles qui remplissent ces espaces réservés.
Définir des fonctions avec des paramètres
Pour définir une fonction qui accepte une entrée, ajoutez des noms de paramètres à l’intérieur des parenthèses :
def greet_person(name):
print(f"Hello, {name}!")
print("Nice to meet you.")
# Appeler avec des arguments différents
greet_person("Alice")
print() # Ligne vide pour la lisibilité
greet_person("Bob")Output:
Hello, Alice!
Nice to meet you.
Hello, Bob!
Nice to meet you.Le paramètre name agit comme une variable à l’intérieur de la fonction. Chaque fois que vous appelez la fonction, name prend la valeur de l’argument que vous fournissez.
Plusieurs paramètres
Les fonctions peuvent accepter plusieurs paramètres, séparés par des virgules :
def calculate_rectangle_area(length, width):
area = length * width
print(f"A rectangle with length {length} and width {width}")
print(f"has an area of {area} square units.")
calculate_rectangle_area(5, 3)
print()
calculate_rectangle_area(10, 7)Output:
A rectangle with length 5 and width 3
has an area of 15 square units.
A rectangle with length 10 and width 7
has an area of 70 square units.Lorsque vous appelez une fonction avec plusieurs paramètres, l’ordre compte. Le premier argument va au premier paramètre, le deuxième argument au deuxième paramètre, et ainsi de suite. On appelle cela des arguments positionnels(positional arguments).
Arguments positionnels
Avec les arguments positionnels, Python associe les arguments aux paramètres en fonction de leur position :
def describe_pet(animal_type, pet_name):
print(f"I have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name}.")
describe_pet("dog", "Buddy")
print()
describe_pet("cat", "Whiskers")Output:
I have a dog.
My dog's name is Buddy.
I have a cat.
My cat's name is Whiskers.Si vous inversez l’ordre, vous obtiendrez des résultats inattendus :
def describe_pet(animal_type, pet_name):
print(f"I have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name}.")
# Arguments dans le mauvais ordre
describe_pet("Buddy", "dog")Output:
I have a Buddy.
My Buddy's name is dog.C’est techniquement du Python valide, mais cela produit une sortie absurde parce que les arguments ne sont pas aux bonnes positions.
Arguments par mot-clé
Pour éviter les erreurs liées à la position, vous pouvez utiliser des arguments par mot-clé(keyword arguments) en nommant explicitement les paramètres lorsque vous appelez la fonction :
def describe_pet(animal_type, pet_name):
print(f"I have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name}.")
# Utilisation d'arguments par mot-clé - l'ordre n'a pas d'importance
describe_pet(animal_type="dog", pet_name="Buddy")
print()
describe_pet(pet_name="Whiskers", animal_type="cat")Output:
I have a dog.
My dog's name is Buddy.
I have a cat.
My cat's name is Whiskers.Avec les arguments par mot-clé, l’ordre n’a pas d’importance car Python associe les arguments aux paramètres par nom, et non par position.
Mélanger arguments positionnels et arguments par mot-clé
Vous pouvez mélanger arguments positionnels et arguments par mot-clé dans un seul appel de fonction, mais les arguments positionnels doivent venir en premier :
def create_profile(username, email, age):
print(f"Username: {username}")
print(f"Email: {email}")
print(f"Age: {age}")
# Mélange d'arguments positionnels et d'arguments par mot-clé
create_profile("alice123", email="alice@example.com", age=25)Output:
Username: alice123
Email: alice@example.com
Age: 25Cependant, vous ne pouvez pas placer des arguments positionnels après des arguments par mot-clé :
# WARNING: This will cause a SyntaxError - for demonstration only
# PROBLEM: Positional argument after keyword argument
# create_profile(username="alice123", "alice@example.com", 25)
# SyntaxError: positional argument follows keyword argumentLe nombre d’arguments doit correspondre
Lorsque vous appelez une fonction, vous devez fournir le bon nombre d’arguments (sauf si la fonction a des valeurs par défaut, que nous verrons au Chapitre 20) :
def add_numbers(a, b):
result = a + b
print(f"{a} + {b} = {result}")
add_numbers(5, 3) # Correct : 2 arguments pour 2 paramètresOutput:
5 + 3 = 8Fournir trop peu ou trop d’arguments provoque une erreur :
# WARNING: These will cause TypeErrors - for demonstration only
# PROBLEM: Too few arguments
# add_numbers(5)
# TypeError: add_numbers() missing 1 required positional argument: 'b'
# PROBLEM: Too many arguments
# add_numbers(5, 3, 2)
# TypeError: add_numbers() takes 2 positional arguments but 3 were givenUtiliser des expressions comme arguments
Les arguments n’ont pas besoin d’être des valeurs simples—vous pouvez utiliser n’importe quelle expression :
def display_total(price, quantity):
total = price * quantity
print(f"Total cost: ${total:.2f}")
# Utiliser des expressions comme arguments
base_price = 10
display_total(base_price * 1.1, 5) # Prix avec une majoration de 10%
display_total(15 + 5, 3 * 2) # Les deux arguments sont des expressionsOutput:
Total cost: $55.00
Total cost: $120.00Python évalue d’abord chaque expression, puis transmet les valeurs résultantes à la fonction.
Appeler des fonctions depuis l’intérieur de fonctions
Les fonctions peuvent appeler d’autres fonctions, créant une hiérarchie d’opérations. C’est une technique puissante qui vous permet de découper des tâches complexes en morceaux plus petits et gérables.
Voici un exemple avec le calcul de la surface d’une pièce :
def calculate_area(length, width):
return length * width
def display_room_info(room_name, length, width):
area = calculate_area(length, width)
print(f"Room: {room_name}")
print(f"Dimensions: {length} x {width}")
print(f"Area: {area} square feet")
display_room_info("Living Room", 15, 12)Output:
Room: Living Room
Dimensions: 15 x 12
Area: 180 square feetNote : Nous utilisons return ici, que nous explorerons en détail dans la section suivante. Pour l’instant, comprenez que calculate_area() renvoie son résultat à la fonction appelante.
Voici un autre exemple montrant comment les fonctions peuvent s’appuyer les unes sur les autres—un système de conversion de température :
def celsius_to_fahrenheit(celsius):
return (celsius * 9/5) + 32
def format_temperature(fahrenheit):
return f"{fahrenheit:.1f}°F"
def display_temperature_conversion(celsius):
fahrenheit = celsius_to_fahrenheit(celsius)
formatted = format_temperature(fahrenheit)
print(f"{celsius}°C equals {formatted}")
# Utiliser le système de conversion complet
display_temperature_conversion(25)
display_temperature_conversion(0)
display_temperature_conversion(100)Output:
25°C equals 77.0°F
0°C equals 32.0°F
100°C equals 212.0°FDans cet exemple, display_temperature_conversion() appelle celsius_to_fahrenheit() pour effectuer la conversion, puis appelle format_temperature() pour formater le résultat. Chaque fonction a une responsabilité unique et claire, ce qui rend le code facile à comprendre et à maintenir.
19.4) Utiliser return pour renvoyer des résultats
Jusqu’ici, nos fonctions ont effectué des actions (comme afficher), mais elles n’ont pas renvoyé de valeurs au code qui les a appelées. L’instruction return permet à une fonction de calculer un résultat et de le renvoyer à l’appelant.
Instruction return de base
Voici une fonction simple qui calcule et renvoie une valeur :
def add_numbers(a, b):
result = a + b
return result
# Récupérer la valeur renvoyée
sum_value = add_numbers(5, 3)
print(f"The sum is: {sum_value}")Output:
The sum is: 8Quand Python rencontre une instruction return, deux choses se produisent :
- La fonction s’arrête immédiatement (tout code après
returnest ignoré) - La valeur spécifiée est renvoyée à l’appelant
Renvoyer des valeurs directement
Vous n’avez pas besoin de stocker le résultat dans une variable avant de le renvoyer. Vous pouvez renvoyer une expression directement :
def multiply(a, b):
return a * b
result = multiply(4, 7)
print(f"4 × 7 = {result}")Output:
4 × 7 = 28C’est plus concis et c’est le style préféré pour les calculs simples.
Utiliser les valeurs renvoyées
Une fois qu’une fonction renvoie une valeur, vous pouvez utiliser cette valeur partout où vous utiliseriez n’importe quelle autre valeur :
def calculate_discount(price, discount_percent):
discount_amount = price * (discount_percent / 100)
return discount_amount
original_price = 100
discount = calculate_discount(original_price, 20)
# Utiliser la valeur renvoyée dans des calculs
final_price = original_price - discount
print(f"Original price: ${original_price:.2f}")
print(f"Discount: ${discount:.2f}")
print(f"Final price: ${final_price:.2f}")Output:
Original price: $100.00
Discount: $20.00
Final price: $80.00return quitte la fonction immédiatement
Quand Python exécute une instruction return, la fonction s’arrête immédiatement. Tout code après le return n’est jamais exécuté :
def check_age(age):
if age < 18:
return "Minor"
# Cette ligne ne s'exécute que si age >= 18
return "Adult"
print(check_age(15))
print(check_age(25))Output:
Minor
AdultCe comportement est utile pour gérer différents cas dans une fonction. Une fois que vous avez déterminé le résultat, vous pouvez renvoyer immédiatement sans avoir besoin de vérifier d’autres conditions.
Voici un exemple qui montre comment return arrête l’exécution :
def process_number(n):
if n < 0:
return "Negative"
print("This line runs for non-negative numbers")
if n == 0:
return "Zero"
print("This line runs for positive numbers")
return "Positive"
print(process_number(-5))
print()
print(process_number(0))
print()
print(process_number(10))Output:
Negative
This line runs for non-negative numbers
Zero
This line runs for non-negative numbers
This line runs for positive numbers
PositiveFonctions sans return
Si une fonction n’a pas d’instruction return, ou si elle a un return sans valeur, la fonction renvoie None :
def greet(name):
print(f"Hello, {name}!")
# Aucune instruction return
result = greet("Alice")
print(f"The function returned: {result}")Output:
Hello, Alice!
The function returned: NoneDe même, un return seul (sans valeur) renvoie aussi None :
def process_data(data):
if not data:
return # Sortie anticipée, renvoie None
print(f"Processing: {data}")
return "Success"
result1 = process_data("")
result2 = process_data("some data")
print(f"Result 1: {result1}")
print(f"Result 2: {result2}")Output:
Processing: some data
Result 1: None
Result 2: SuccessRenvoyer plusieurs valeurs
Les fonctions Python peuvent renvoyer plusieurs valeurs en les séparant par des virgules. Python les empaquette automatiquement dans un tuple (comme nous l’avons appris au Chapitre 15) :
def calculate_rectangle(length, width):
area = length * width
perimeter = 2 * (length + width)
return area, perimeter
# Dépaqueter le tuple renvoyé
rect_area, rect_perimeter = calculate_rectangle(5, 3)
print(f"Area: {rect_area}")
print(f"Perimeter: {rect_perimeter}")Output:
Area: 15
Perimeter: 16Vous pouvez aussi capturer le tuple comme une valeur unique :
def get_student_info():
name = "Alice"
age = 20
grade = "A"
return name, age, grade
# Capturer comme un tuple
student = get_student_info()
print(f"Student info: {student}")
print(f"Name: {student[0]}")Output:
Student info: ('Alice', 20, 'A')
Name: AliceRenvoyer différents types
Une fonction peut renvoyer différents types de valeurs selon la situation :
def divide(a, b):
if b == 0:
return "Error: Division by zero"
return a / b
result1 = divide(10, 2)
result2 = divide(10, 0)
print(f"10 / 2 = {result1}")
print(f"10 / 0 = {result2}")Output:
10 / 2 = 5.0
10 / 0 = Error: Division by zeroMême si cela fonctionne, il est généralement préférable de gérer les erreurs différemment (nous apprendrons les exceptions dans la Partie VII). Pour l’instant, comprenez que les fonctions peuvent renvoyer différents types, même si c’est souvent plus clair d’être cohérent.
19.5) Documenter les fonctions avec des docstrings
À mesure que vos programmes grandissent et que vous créez plus de fonctions, il devient crucial de documenter ce que fait chaque fonction. Python fournit une manière intégrée de documenter les fonctions en utilisant des docstrings(docstrings) (chaînes de documentation).
Qu’est-ce qu’une docstring ?
Une docstring(docstring) est un littéral de chaîne qui apparaît comme la première instruction d’une fonction (ou d’un module, d’une classe, ou d’une méthode). Elle décrit ce que fait la fonction, quels paramètres elle accepte, et ce qu’elle renvoie. Les docstrings sont entourées de guillemets triples (""" ou '''), ce qui leur permet de s’étendre sur plusieurs lignes.
def calculate_area(length, width):
"""Calculate the area of a rectangle.
Takes the length and width of a rectangle and returns the area.
"""
return length * widthPourquoi les docstrings comptent
Les docstrings remplissent plusieurs objectifs importants :
- Auto-documentation : elles expliquent ce que fait votre fonction sans obliger les lecteurs à analyser le code
- Support des IDE : de nombreux outils de développement affichent les docstrings comme des info-bulles quand vous utilisez une fonction
- Fonction help() : la fonction intégrée
help()de Python affiche les docstrings - Pratique professionnelle : un code bien documenté est plus facile à maintenir et à partager avec d’autres
Format de docstring de base
Pour des fonctions simples, une docstring sur une seule ligne suffit :
def greet(name):
"""Print a personalized greeting."""
print(f"Hello, {name}!")
# Accéder à la docstring
print(greet.__doc__)Output:
Print a personalized greeting.La docstring doit être une description concise de ce que fait la fonction, écrite comme une commande (« Calculate... », « Return... », « Print... ») plutôt qu’une description (« This function calculates... »).
Docstrings multi-lignes
Pour des fonctions plus complexes, utilisez des docstrings multi-lignes qui incluent :
- Un bref résumé sur la première ligne
- Une ligne vide
- Une description plus détaillée
- Des informations sur les paramètres
- Des informations sur les valeurs de retour
def calculate_discount(price, discount_percent):
"""Calculate the discounted price.
Takes an original price and a discount percentage, then returns
the amount of discount that should be applied.
Parameters:
price (float): The original price before discount
discount_percent (float): The discount percentage (0-100)
Returns:
float: The discount amount in the same currency as the price
"""
return price * (discount_percent / 100)
# Utiliser help() pour voir la docstring complète
help(calculate_discount)Output:
Help on function calculate_discount in module __main__:
calculate_discount(price, discount_percent)
Calculate the discounted price.
Takes an original price and a discount percentage, then returns
the amount of discount that should be applied.
Parameters:
price (float): The original price before discount
discount_percent (float): The discount percentage (0-100)
Returns:
float: The discount amount in the same currency as the priceConventions des docstrings
Python a établi des conventions pour écrire des docstrings (documentées dans la PEP 257). Voici les principales règles :
1. Utiliser des triples guillemets doubles : """docstring"""
def good_example():
"""This follows the convention."""
pass
def also_valid():
'''This works but is less common.'''
pass2. Les docstrings sur une ligne doivent tenir sur une seule ligne :
def add(a, b):
"""Return the sum of a and b."""
return a + b3. Les docstrings multi-lignes doivent avoir une ligne de résumé, puis une ligne vide :
def process_order(order_id, items):
"""Process a customer order and update inventory.
This function validates the order, checks inventory availability,
calculates the total cost, and updates the inventory database.
Parameters:
order_id (str): Unique identifier for the order
items (list): List of item dictionaries with 'product' and 'quantity'
Returns:
dict: Order summary with 'total', 'status', and 'confirmation_number'
"""
# Implémentation de la fonction ici
passDécrire les paramètres et les valeurs de retour
Lorsque vous documentez les paramètres et les valeurs de retour, soyez précis concernant :
- Noms des paramètres : correspondre aux noms de paramètres réels dans la fonction
- Types : quel type de données est attendu (nous apprendrons les annotations de types au Chapitre 43)
- Objectif : à quoi sert le paramètre
- Valeur de retour : ce que la fonction renvoie et sous quelles conditions
def find_student(student_id, students):
"""Find a student by ID in a list of student records.
Parameters:
student_id (int): The unique ID number of the student to find
students (list): List of student dictionaries, each containing 'id' and 'name'
Returns:
dict: The student dictionary if found, None if not found
"""
for student in students:
if student['id'] == student_id:
return student
return NoneDocstrings pour les fonctions avec plusieurs types de retour
Quand une fonction peut renvoyer différents types selon la situation, documentez toutes les possibilités :
def safe_divide(a, b):
"""Divide two numbers with error handling.
Parameters:
a (float): The dividend
b (float): The divisor
Returns:
float: The quotient if division is successful
str: An error message if b is zero
"""
if b == 0:
return "Error: Cannot divide by zero"
return a / bAccéder aux docstrings
Vous pouvez accéder à la docstring d’une fonction de trois façons :
1. En utilisant l’attribut __doc__ :
def example():
"""This is an example function."""
pass
print(example.__doc__)Output:
This is an example function.2. En utilisant la fonction help() :
def calculate_bmi(weight, height):
"""Calculate Body Mass Index.
Parameters:
weight (float): Weight in kilograms
height (float): Height in meters
Returns:
float: BMI value
"""
return weight / (height ** 2)
help(calculate_bmi)Output:
Help on function calculate_bmi in module __main__:
calculate_bmi(weight, height)
Calculate Body Mass Index.
Parameters:
weight (float): Weight in kilograms
height (float): Height in meters
Returns:
float: BMI value3. Dans les environnements de développement interactifs : la plupart des IDE et éditeurs de code affichent les docstrings comme des info-bulles lorsque vous survolez ou tapez un nom de fonction.
Quand écrire des docstrings
Vous devriez écrire des docstrings pour :
- Toutes les fonctions publiques : les fonctions destinées à être utilisées par d’autres parties de votre programme ou par d’autres programmeurs
- Les fonctions complexes : toute fonction dont l’objectif ou le comportement n’est pas immédiatement évident à partir de son nom et de ses paramètres
- Les fonctions avec des paramètres non évidents : lorsque les noms de paramètres seuls n’expliquent pas complètement quelles valeurs sont attendues
Vous pouvez omettre les docstrings pour :
- Des fonctions très simples et évidentes : des fonctions comme
def add(a, b): return a + boù le nom et les paramètres rendent l’objectif parfaitement clair - Des fonctions utilitaires privées : de petites fonctions internes utilisées uniquement au sein d’une fonction plus grande (même si celles-ci bénéficient aussi de docstrings brèves)
Les docstrings ne sont pas des commentaires
Rappelez-vous que les docstrings ont un objectif différent de celui des commentaires :
- Docstrings : décrivent ce que fait une fonction et comment l’utiliser (l’interface)
- Commentaires : expliquent comment le code fonctionne en interne (l’implémentation)
def calculate_grade(score, total):
"""Calculate the percentage grade from a score.
Parameters:
score (int): Points earned
total (int): Total points possible
Returns:
float: The percentage grade (0-100)
"""
# Éviter une division par zéro
if total == 0:
return 0.0
# Calculer le pourcentage et arrondir à 2 décimales
percentage = (score / total) * 100
return round(percentage, 2)La docstring indique aux utilisateurs ce que fait la fonction et comment l’utiliser. Les commentaires expliquent des détails spécifiques d’implémentation à quelqu’un qui lit le code.
Développer de bonnes habitudes de documentation
Écrire des docstrings claires est une habitude qui porte ses fruits :
- Écrivez les docstrings pendant que vous écrivez les fonctions : n’attendez pas plus tard—documentez pendant que l’objectif de la fonction est frais dans votre esprit
- Gardez les docstrings à jour : quand vous changez le comportement d’une fonction, mettez à jour sa docstring
- Soyez concis mais complet : incluez toutes les informations nécessaires, mais évitez une verbosité inutile
- Utilisez des exemples quand c’est utile : pour les fonctions complexes, un exemple d’utilisation dans la docstring peut être inestimable
Une bonne documentation rend votre code plus professionnel, plus facile à maintenir, et plus utile pour les autres (y compris votre vous futur).