// Python

Les fonctions en Python : tout ce qu'il faut savoir

Une fonction Python est un bloc de code réutilisable, nommé, qui accomplit une tâche précise. Bien maîtrisées, les fonctions rendent votre code plus lisible, plus court et plus facile à tester. Ce guide couvre de façon exhaustive tout ce qu’il faut savoir : définition avec def, les différents types d’arguments, la valeur de retour, la portée des variables, les fonctions lambda, les docstrings et les annotations de type.

Définir une fonction avec def

On déclare une fonction avec le mot-clé def, suivi du nom, de parenthèses et de deux-points. Le corps est indenté.

def saluer():
    print("Bonjour !")

saluer()   # appelle la fonction -> Bonjour !

Une fonction n’exécute rien tant qu’on ne l’appelle pas avec ses parenthèses. Le nom suit la convention snake_case (minuscules et underscores).

Les paramètres et arguments

Une fonction peut recevoir des données via ses paramètres.

def saluer(nom):
    print(f"Bonjour {nom} !")

saluer("Alice")   # Bonjour Alice !

On parle de paramètre dans la définition (nom) et d’argument lors de l’appel ("Alice"). Une fonction peut prendre plusieurs paramètres, séparés par des virgules.

Arguments positionnels

Les arguments positionnels sont transmis dans l’ordre des paramètres.

def diviser(a, b):
    return a / b

print(diviser(10, 2))   # 5.0 : a=10, b=2

L’ordre compte : diviser(2, 10) donnerait 0.2.

Arguments nommés (keyword arguments)

On peut préciser le nom du paramètre à l’appel, ce qui libère de l’ordre et clarifie l’intention.

def presenter(prenom, ville):
    print(f"{prenom} habite à {ville}")

presenter(ville="Lyon", prenom="Marie")
# Marie habite à Lyon

Valeurs par défaut

Un paramètre peut avoir une valeur par défaut, utilisée si l’argument est omis.

def puissance(base, exposant=2):
    return base ** exposant

print(puissance(5))       # 25 (exposant vaut 2 par défaut)
print(puissance(5, 3))    # 125

Règle importante : ne jamais utiliser un objet mutable (liste, dictionnaire) comme valeur par défaut. Écrivez def f(items=None) puis if items is None: items = [] à l’intérieur, sinon la valeur est partagée entre tous les appels.

*args : nombre variable d’arguments positionnels

*args capture un nombre indéfini d’arguments positionnels sous forme de tuple.

def somme(*nombres):
    total = 0
    for n in nombres:
        total += n
    return total

print(somme(1, 2, 3))        # 6
print(somme(4, 5, 6, 7, 8))  # 30

**kwargs : nombre variable d’arguments nommés

**kwargs capture les arguments nommés dans un dictionnaire.

def profil(**infos):
    for cle, valeur in infos.items():
        print(f"{cle} : {valeur}")

profil(nom="Durand", age=30, ville="Nantes")
# nom : Durand
# age : 30
# ville : Nantes

On combine souvent tout : def f(a, b, *args, **kwargs). L’ordre à respecter dans la signature est : positionnels, *args, arguments nommés, puis **kwargs.

La valeur de retour (return)

return renvoie un résultat et met fin à l’exécution de la fonction.

def carre(x):
    return x * x

resultat = carre(4)   # 16

Sans return, une fonction renvoie implicitement None. On peut renvoyer plusieurs valeurs d’un coup grâce aux tuples :

def minmax(nombres):
    return min(nombres), max(nombres)

petit, grand = minmax([3, 1, 7, 2])
print(petit, grand)   # 1 7

Tout code placé après un return exécuté est ignoré ; c’est pratique pour un retour anticipé (if erreur: return None).

La portée des variables (scope)

Une variable créée dans une fonction est locale : elle n’existe pas à l’extérieur.

def compteur():
    x = 10      # variable locale
    return x

compteur()
# print(x) provoquerait une NameError

Pour modifier une variable globale depuis une fonction, on utilise le mot-clé global, mais c’est généralement déconseillé : préférez renvoyer une valeur.

total = 0

def ajouter(n):
    global total
    total += n

ajouter(5)
print(total)   # 5

Python applique la règle LEGB (Local, Enclosing, Global, Built-in) pour résoudre le nom d’une variable. Si vous découpez déjà votre programme en fonctions, jetez un œil à nos listes en Python souvent passées en argument.

Les fonctions lambda

Une lambda est une fonction anonyme, tenant sur une seule ligne. Elle sert pour de petites opérations, notamment comme paramètre key.

double = lambda x: x * 2
print(double(6))   # 12

# Trier une liste de tuples par le second élément
paires = [(1, "b"), (2, "a"), (3, "c")]
paires.sort(key=lambda p: p[1])
# [(2, 'a'), (1, 'b'), (3, 'c')]

Une lambda ne contient qu’une seule expression, dont le résultat est automatiquement renvoyé. Pour une logique plus complexe, écrivez une vraie fonction def.

Les docstrings

Une docstring documente la fonction. Placée juste après la ligne def, entre triples guillemets, elle est accessible via help() ou l’attribut __doc__.

def moyenne(nombres):
    """Renvoie la moyenne d'une liste de nombres.

    Args:
        nombres (list): la liste de valeurs numériques.

    Returns:
        float: la moyenne arithmétique.
    """
    return sum(nombres) / len(nombres)

print(moyenne.__doc__)

Documenter ses fonctions est une excellente habitude, surtout dans un projet partagé.

Les annotations de type

Les annotations précisent les types attendus des paramètres et du retour. Elles n’imposent rien à l’exécution mais aident la lecture et les outils comme mypy.

def additionner(a: int, b: int) -> int:
    return a + b

def saluer(nom: str, majuscule: bool = False) -> str:
    message = f"Bonjour {nom}"
    return message.upper() if majuscule else message

Le -> int indique le type de retour. Ces indices de type rendent votre code auto-documenté et facilitent la détection d’erreurs avant même de lancer le programme.

Bonnes pratiques

  • Une fonction = une responsabilité claire.
  • Un nom explicite (un verbe : calculer_total, est_valide).
  • Éviter les fonctions trop longues : découpez.
  • Renvoyer plutôt que de modifier des variables globales.
  • Documenter avec une docstring dès que la logique n’est pas triviale.

Conclusion

Vous connaissez maintenant l’essentiel des fonctions Python : def, arguments positionnels et nommés, valeurs par défaut, *args/**kwargs, return, portée, lambda, docstrings et annotations de type. Ces briques sont le socle de tout programme structuré. L’étape suivante logique consiste à regrouper des fonctions et des données au sein d’objets.

À lire ensuite