Skip to content

Fonctions en Python

Une fonction est un bloc de code nommé et réutilisable, conçu pour exécuter une tâche spécifique. Les fonctions aident à organiser le code, à rendre les applications plus modulaires, à améliorer la lisibilité et à favoriser la réutilisation du code.

Python fournit de nombreuses fonctions intégrées (par exemple, print(), len(), type()). Vous pouvez également définir vos propres fonctions, appelées fonctions définies par l’utilisateur.

Les fonctions sont définies à l’aide du mot-clé def, suivi du nom de la fonction, de parenthèses () et d’un deux-points :. Le bloc de code à l’intérieur de la fonction doit être indenté.

  • La syntaxe commence par def nom_de_la_fonction(paramètres):.
  • Les paramètres (inputs de la fonction) sont listés entre parenthèses, séparés par des virgules. Une fonction peut avoir zéro ou plusieurs paramètres.
  • La première instruction peut être une chaîne de documentation (docstring) facultative, entourée de triples guillemets ("""La docstring va ici"""), expliquant ce que fait la fonction. C’est fortement recommandé.
  • Le bloc de code indenté suivant le deux-points est le corps de la fonction (suite).
  • L’instruction return quitte la fonction et renvoie éventuellement une valeur à l’appelant. Si return est omis ou utilisé sans expression, la fonction renvoie implicitement None.
def function_name(parameter1, parameter2=default_value):
"""Docstring facultative expliquant la fonction."""
# Corps de la fonction (code indenté)
result = parameter1 + parameter2
return result # Instruction return facultative

Une fonction simple qui prend un nom et affiche un salut :

def greet(name):
"""Affiche un simple salut au nom donné."""
print(f"Hello, {name}!")
# Renvoie implicitement None

Définir une fonction ne l’exécute pas. Pour exécuter le code à l’intérieur d’une fonction, vous devez l’appeler en utilisant son nom suivi de parenthèses, en fournissant les arguments requis.

# Définir d'abord la fonction
def greet(name):
"""Affiche un simple salut."""
print(f"Hello, {name}!")
# Maintenant, appeler la fonction
greet("Alice")
greet("Bob")

Sortie :

Hello, Alice!
Hello, Bob!

Passage d’arguments (Passage par référence d’objet)

Section titled “Passage d’arguments (Passage par référence d’objet)”

En Python, les arguments sont passés en utilisant un mécanisme parfois appelé “passage par référence d’objet” (pass by object reference) ou “passage par affectation” (pass by assignment). Voici ce que cela signifie :

Exemple (Objet mutable) :

def modify_list(my_list):
"""Ajoute un élément à la liste passée."""
my_list.append(100) # Modifie l'objet liste original
print(f"Inside function: {my_list}")
numbers = [10, 20, 30]
modify_list(numbers)
print(f"Outside function: {numbers}") # Le changement persiste

Sortie :

Inside function: [10, 20, 30, 100]
Outside function: [10, 20, 30, 100]

Exemple (Réaffectation) :

def reassign_list(my_list):
"""Réaffecte le paramètre à une nouvelle liste."""
my_list = [1, 2, 3, 4] # Le paramètre pointe maintenant vers une *nouvelle* liste
print(f"Inside function (after reassign): {my_list}")
numbers = [10, 20, 30]
reassign_list(numbers)
print(f"Outside function: {numbers}") # La liste originale n'est pas affectée

Sortie :

Inside function (after reassign): [1, 2, 3, 4]
Outside function: [10, 20, 30]

Python offre des moyens flexibles de définir et d’appeler des fonctions avec différents types d’arguments :

Ce sont les arguments standards, mis en correspondance en fonction de leur ordre. Le nombre d’arguments dans l’appel doit correspondre au nombre de paramètres.

def describe_pet(animal_type, pet_name):
print(f"I have a {animal_type} named {pet_name}.")
describe_pet("hamster", "Harry") # Ordre correct
# describe_pet("Fluffy") # TypeError : il manque 1 argument positionnel requis : 'pet_name'

Vous pouvez spécifier les arguments par nom de paramètre dans l’appel de fonction. Cela vous permet de passer les arguments dans n’importe quel ordre et améliore la clarté.

def describe_pet(animal_type, pet_name):
print(f"I have a {animal_type} named {pet_name}.")
describe_pet(pet_name="Willie", animal_type="dog") # L'ordre n'a pas d'importance
describe_pet(animal_type="cat", pet_name="Whiskers")

Vous pouvez fournir des valeurs par défaut pour les paramètres dans la définition de la fonction. Si un argument pour ce paramètre n’est pas fourni lors de l’appel, la valeur par défaut est utilisée. Les paramètres avec des valeurs par défaut doivent venir après les paramètres sans valeurs par défaut.

def describe_pet(pet_name, animal_type="dog"): # valeur par défaut pour animal_type
print(f"I have a {animal_type} named {pet_name}.")
describe_pet(pet_name="Buddy") # Utilise la valeur par défaut 'dog' pour animal_type
describe_pet(pet_name="Lucy", animal_type="cat") # Écrase la valeur par défaut

Sortie :

I have a dog named Buddy.
I have a cat named Lucy.

Pour permettre à une fonction d’accepter un nombre arbitraire d’arguments positionnels, utilisez un astérisque * avant un nom de paramètre (conventionnellement *args). Cela rassemble tous les arguments positionnels supplémentaires dans un tuple.

def make_pizza(size, *toppings):
"""Affiche la pizza commandée avec ses garnitures."""
print(f"\nMaking a {size}-inch pizza with the following toppings:")
if toppings:
for topping in toppings:
print(f"- {topping}")
else:
print("- Plain")
make_pizza(12, "mushrooms")
make_pizza(16, "pepperoni", "green peppers", "extra cheese")
make_pizza(10) # Pas d'arguments positionnels supplémentaires, le tuple toppings est vide

Sortie :

Making a 12-inch pizza with the following toppings:
- mushrooms
Making a 16-inch pizza with the following toppings:
- pepperoni
- green peppers
- extra cheese
Making a 10-inch pizza with the following toppings:
- Plain

5. Arguments par mot-clé à longueur variable (**kwargs)

Section titled “5. Arguments par mot-clé à longueur variable (**kwargs)”

Pour permettre à une fonction d’accepter un nombre arbitraire d’arguments par mot-clé, utilisez deux astérisques ** avant un nom de paramètre (conventionnellement **kwargs). Cela rassemble tous les arguments par mot-clé supplémentaires dans un dictionnaire.

def build_profile(first, last, **user_info):
"""Construit un dictionnaire contenant les informations de l'utilisateur."""
profile = {'first_name': first, 'last_name': last}
profile.update(user_info) # Ajouter les kwargs supplémentaires
return profile
user1 = build_profile('albert', 'einstein',
location='princeton',
field='physics')
user2 = build_profile('marie', 'curie', field='chemistry', awards=2)
print(user1)
print(user2)

Sortie :

{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}
{'first_name': 'marie', 'last_name': 'curie', 'field': 'chemistry', 'awards': 2}

6. Arguments par mot-clé uniquement (Python 3)

Section titled “6. Arguments par mot-clé uniquement (Python 3)”

Les arguments placés après *args ou un * nu doivent être spécifiés à l’aide de mots-clés.

def process_data(*, input_file, output_file, force=False):
"""Nécessite que input_file et output_file soient passés par mot-clé."""
print(f"Processing {input_file} to {output_file}. Force={force}")
# process_data("in.txt", "out.txt") # TypeError !
process_data(input_file="in.csv", output_file="out.csv")
process_data(input_file="data.zip", output_file="proc.zip", force=True)

7. Arguments positionnels uniquement (Python 3.8+)

Section titled “7. Arguments positionnels uniquement (Python 3.8+)”

Les arguments placés avant un / nu ne peuvent être spécifiés que par position, et non par mot-clé.

def example_pos_only(a, b, / , c, d):
"""a et b sont positionnels uniquement."""
print(f"a={a}, b={b}, c={c}, d={d}")
example_pos_only(1, 2, c=3, d=4) # Fonctionne
# example_pos_only(a=1, b=2, c=3, d=4) # TypeError ! a et b sont positionnels uniquement

Les fonctions lambda (lambda functions) offrent une syntaxe abrégée pour créer de petites fonctions anonymes (fonctions sans nom). Elles sont définies à l’aide du mot-clé lambda.

  • Syntaxe : lambda arguments: expression
  • Peut prendre n’importe quel nombre d’arguments mais ne peut avoir qu’une seule expression.
  • L’expression est évaluée et renvoyée lorsque la fonction lambda est appelée.
  • Souvent utilisée lorsqu’un simple objet fonction est requis (par exemple, comme arguments pour map(), filter(), sorted()).

Exemple :

# Équivalent à : def add(x, y): return x + y
adder = lambda x, y: x + y
print(f"Value of total: {adder(10, 20)}")
print(f"Value of total: {adder(5, -2)}")
# Utilisation de lambda avec sorted()
points = [(1, 2), (3, 1), (5, -4), (2, 3)]
# Trier les points en fonction du deuxième élément (coordonnée y)
points_sorted_by_y = sorted(points, key=lambda point: point[1])
print(f"Sorted by y: {points_sorted_by_y}")

Sortie :

Value of total: 30
Value of total: 3
Sorted by y: [(5, -4), (3, 1), (1, 2), (2, 3)]

L’instruction return est utilisée pour quitter une fonction et renvoyer une valeur à l’endroit où la fonction a été appelée. Une fonction peut renvoyer n’importe quel type d’objet.

def subtract(arg1, arg2):
"""Soustrait arg2 de arg1 et renvoie le résultat."""
total = arg1 - arg2
print(f"Inside the function, result: {total}")
return total
# Appeler la fonction et stocker la valeur renvoyée
result_value = subtract(20, 5)
print(f"Outside the function, result: {result_value}")
# Peut renvoyer plusieurs valeurs (sous forme de tuple)
def get_coordinates():
return 10, 20 # Automatiquement emballé dans un tuple
x, y = get_coordinates() # Déballer le tuple renvoyé
print(f"Coordinates: x={x}, y={y}")

Sortie :

Inside the function, result: 15
Outside the function, result: 15
Coordinates: x=10, y=20

La portée (scope) d’une variable détermine où elle peut être accédée dans le programme.

Python recherche un nom de variable dans cet ordre LEGB.

total = 0 # Variable globale
def sum_and_update(arg1, arg2):
# 'total' ici fait référence à une *nouvelle* variable locale
# sauf si déclarée globale
# global total # Décommentez ceci pour modifier la variable globale 'total'
total = arg1 + arg2 # Crée une variable 'total' locale, qui masque la globale
print(f"Inside function local total: {total}")
return total
sum_and_update(10, 20)
print(f"Outside function global total: {total}") # La variable globale 'total' reste inchangée

Sortie (sans global total décommenté) :

Inside function local total: 30
Outside function global total: 0

Indication de type (Type Hinting) (PEP 484)

Section titled “Indication de type (Type Hinting) (PEP 484)”

Python moderne (3.5+) prend en charge les indications de type (type hints) facultatives, vous permettant d’annoter les paramètres de fonction et les valeurs de retour avec leurs types attendus. Les indications de type n’affectent pas le comportement à l’exécution (runtime) mais sont inestimables pour les outils d’analyse statique (comme MyPy), les IDE et l’amélioration de la clarté du code.

import math
def calculate_circumference(radius: float) -> float:
"""Calcule la circonférence d'un cercle à partir de son rayon."""
if radius < 0:
raise ValueError("Radius cannot be negative")
return 2 * math.pi * radius
# Les indications de type aident à détecter les erreurs potentielles statiquement
circum = calculate_circumference(10.5)
print(f"Circumference: {circum:.2f}")
# MyPy signalerait cet appel si exécuté :
# result_wrong_type = calculate_circumference("hello")

Les types courants sont importés du module typing (par exemple, List, Dict, Tuple, Optional).