Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Licence CC BY-NC-ND Thierry Parmentelat & Arnaud Legout Inria - UCA

Complément - niveau basique

N’utilisez pas d’objet mutable pour les valeurs par défaut

En Python il existe un piège dans lequel il est très facile de tomber. Aussi si vous voulez aller à l’essentiel : n’utilisez pas d’objet mutable pour les valeurs par défaut lors de la définition d’une fonction.

Si vous avez besoin d’écrire une fonction qui prend en argument par défaut une liste ou un dictionnaire vide, voici comment faire

# ne faites SURTOUT PAS ça
def ne_faites_pas_ca(options={}):
    "faire quelque chose"
# mais plutôt comme ceci
def mais_plutot_ceci(options=None):
    if options is None: 
        options = {}
    "faire quelque chose"
The history saving thread hit an unexpected error (OperationalError('disk I/O error')).History will not be written to the database.

Complément - niveau intermédiaire

Que se passe-t-il si on le fait ?

Considérons le cas relativement simple d’une fonction qui calcule une valeur - ici un entier aléatoire entre 0 et 10 -, et l’ajoute à une liste passée par l’appelant.

Et pour rendre la vie de l’appelant plus facile, on se dit qu’il peut être utile de faire en sorte que si l’appelant n’a pas de liste sous la main, on va créer pour lui une liste vide. Et pour ça on fait :

import random

# l'intention ici est que si l'appelant ne fournit pas 
# la liste en entrée, on crée pour lui une liste vide
def ajouter_un_aleatoire(resultats=[]):
    resultats.append(random.randint(0, 10))
    return resultats

Si on appelle cette fonction une première fois, tout semble bien aller

ajouter_un_aleatoire()
[1]

Sauf que, si on appelle la fonction une deuxième fois, on a une surprise !

ajouter_un_aleatoire()
[1, 2]

Pourquoi ?

Le problème ici est qu’une valeur par défaut - ici l’expression [] - est évaluée une fois au moment de la définition de la fonction.

Toutes les fois où la fonction est appelée avec cet argument manquant, on va utiliser comme valeur par défaut le même objet, qui la première fois est bien une liste vide, mais qui se fait modifier par le premier appel.

Si bien que la deuxième fois on réutilise la même liste qui n’est plus vide. Pour aller plus loin, vous pouvez regarder la documentation Python sur ce problème.