web-dev-qa-db-fra.com

Paramètres facultatifs dans les fonctions Python et leurs valeurs par défaut

Duplicata possible:
"Le moindre étonnement" en Python: l'argument par défaut Mutable

Je suis un peu confus sur le fonctionnement des paramètres facultatifs dans Python fonctions/méthodes.

J'ai le bloc de code suivant:

>>> def F(a, b=[]):
...     b.append(a)
...     return b
...
>>> F(0)
[0]
>>> F(1)
[0, 1]
>>>

Pourquoi F(1) renvoie [0, 1] Et non [1]?

Je veux dire, ce qui se passe à l'intérieur ?

35
Oscar Mederos

Bon doc de PyCon il y a quelques années - Les valeurs des paramètres par défaut expliquées . Mais fondamentalement, puisque les listes sont des objets mutables et que les arguments de mots clés sont évalués au moment de la définition de la fonction, chaque fois que vous appelez la fonction, vous obtenez la même valeur par défaut.

La bonne façon de procéder serait:

def F(a, b=None):
    if b is None:
        b = []
    b.append(a)
    return b
43
Ben Hayden

Paramètres par défaut sont, de manière assez intuitive, un peu comme les variables membres sur l'objet fonction.

Les valeurs des paramètres par défaut sont évaluées lors de l'exécution de la définition de fonction. Cela signifie que l'expression est évaluée une fois, lorsque la fonction est définie, et que la même valeur "pré-calculée" est utilisée pour chaque appel. Ceci est particulièrement important pour comprendre quand un paramètre par défaut est un objet modifiable, comme une liste ou un dictionnaire: si la fonction modifie l'objet (par exemple en ajoutant un élément à une liste), la valeur par défaut est en effet modifiée.

http://docs.python.org/reference/compound_stmts.html#function

Les listes sont des objets mutables; vous pouvez modifier leur contenu. La bonne façon d'obtenir une liste par défaut (ou un dictionnaire, ou un ensemble) est de la créer au moment de l'exécution à la place, dans la fonction:

def good_append(new_item, a_list=None):
    if a_list is None:
        a_list = []
    a_list.append(new_item)
    return a_list
9
Jonas Elfström