Bases & algorithmique · 6 mondes · 18 étapes

Python avancé

Le langage lui-même : texte, compréhensions, objets, erreurs, modules.

Progression

0 %

0/18 étapes terminées

Intermédiaire · 10 min de lecture

Fonctions avancées

Signatures, défauts, et fonctions comme valeurs

1Définition

Une fonction Python accepte des arguments par position ou par nom, des valeurs par défaut, un nombre libre d'arguments (*args, **kwargs), et peut être manipulée comme une valeur : stockée, passée, renvoyée.

2Principes fondamentaux

01

La signature est une documentation

badge(nom, niveau=1, actif=True) dit tout : ce qui est obligatoire, ce qui est optionnel, et les valeurs normales.

02

Jamais de défaut mutable

Une liste par défaut est créée une seule fois et partagée entre tous les appels. On met None et on crée dans le corps.

03

Clause de garde en premier

Les cas impossibles se traitent en tête de fonction, ce qui laisse le corps principal linéaire et lisible.

04

Une fonction est une valeur

C'est ce qui permet sorted(key=...), map, les décorateurs et les rappels. Comprendre ça change la façon de découper un programme.

3Exemples pratiques

Le piège du défaut mutable

Exemple
1def ajouter_faux(element, liste=[]):2    liste.append(element)3    return liste4 5print(ajouter_faux(1))   # [1]6print(ajouter_faux(2))   # [1, 2]  ← la liste a survécu7 8def ajouter(element, liste=None):9    if liste is None:10        liste = []11    liste.append(element)12    return liste

La valeur par défaut est évaluée à la définition, pas à chaque appel. C'est le piège le plus célèbre du langage.

Ordre supérieur et réduction

Exemple
1def appliquer(operation, depart, *valeurs):2    resultat = depart3    for v in valeurs:4        resultat = operation(resultat, v)5    return resultat6 7print(appliquer(lambda a, b: a + b, 0, 4, 8, 15))   # 278print(appliquer(lambda a, b: a * b, 1, 2, 3, 4))    # 24

Une seule fonction, deux comportements : c'est le mécanisme derrière sum, max et functools.reduce.

4Erreurs courantes

Défaut avant obligatoire

À éviter

def badge(niveau=1, nom):

À faire

def badge(nom, niveau=1):

Pourquoi : SyntaxError : l'appel serait ambigu. Les paramètres sans défaut viennent toujours en premier.

Lambda trop ambitieuse

À éviter

traiter = lambda x: (nettoyer(x), verifier(x), enregistrer(x))

À faire

def traiter(x):    nettoyer(x)    verifier(x)    enregistrer(x)

Pourquoi : Une lambda ne contient qu'une expression. La forcer à en faire plus produit du code illisible et non déboguable.

Une fonction qui fait trois choses

À éviter

def traiter():    # lit le fichier, calcule, affiche et enregistre

À faire

# lire(), calculer(), afficher(), enregistrer()

Pourquoi : Une fonction, une responsabilité : c'est ce qui rend les tests possibles et la réutilisation naturelle.

5Subtilités à connaître

  • ◆* seul dans une signature force les arguments suivants à être nommés : def f(a, *, verbose=False).
  • ◆Les annotations de type (def f(nom: str) -> str:) ne sont pas vérifiées à l'exécution, mais elles documentent et alimentent les outils d'analyse.
  • ◆Une fonction définie dans une autre capture les variables environnantes : c'est une fermeture, la base des décorateurs.

6Vérifie ta compréhension

Question 1/3

Score 0

Quand la valeur par défaut est-elle évaluée ?

Envie d'essayer ? Ouvre le Labo et recopie les exemples pour les modifier.