Quiconque utilise Python depuis longtemps sera troublé (ou mis en pièces) par les questions suivantes :
def foo(a=[]): a.append(5) return a
Les débutants en python s'attendront à ce que cette fonction, appelée sans arguments, renvoie toujours une liste avec un seul élément : [5]
. Le résultat est très différent et assez surprenant (pour les débutants) :
>>> foo() [5] >>> foo() [5, 5] >>> foo() [5, 5, 5] >>> foo() [5, 5, 5, 5] >>> foo()
Un de mes managers a rencontré cette fonctionnalité pour la première fois et l'a qualifiée de "défaut de conception dramatique" dans le langage. J'ai répondu qu'il y avait une explication sous-jacente à ce comportement, et qu'il serait en effet très déroutant et inattendu si l'on n'en comprenait pas les composants internes. Cependant, je ne peux pas répondre (à moi-même) à la question suivante : quelle est la raison de la liaison des paramètres par défaut au moment de la définition de la fonction plutôt qu'au moment de l'exécution de la fonction ? Je doute que le comportement expérimenté ait une quelconque utilité pratique (qui utilise réellement des variables statiques en C sans engendrer de bugs ?)
Éditeur :
baczek a donné un exemple intéressant. En conjonction avec la plupart de vos commentaires, notamment ceux d'utaal, je développe plus en détail :
def a(): print("a executed") return [] def b(x=a()): x.append(5) print(x) a executed >>> b() [5] >>> b() [5, 5]
Pour moi, la décision de conception semble être liée à l'endroit où placer la portée du paramètre : à l'intérieur de la fonction, ou « avec » la fonction ?
La liaison à l'intérieur d'une fonction signifie que la ligne x
在调用函数时有效地绑定到指定的默认值,而不是定义,这会带来严重的缺陷:def
sera "mixte" dans la mesure où une partie de la liaison (de l'objet fonction) se produira au moment de la définition et une partie (affectation des paramètres par défaut) se produira au moment de l'appel de la fonction.
Le comportement réel est plus cohérent : lorsque la ligne est exécutée, c'est-à-dire au moment de la définition de la fonction, tout ce qui se trouve dans la ligne est évalué.
En fait, ce n'est pas un défaut de conception, ni dû à des raisons internes ou de performances. Cela vient du fait que les fonctions en Python sont des objets de première classe, pas seulement des morceaux de code.
Cela prend tout son sens quand on y réfléchit de cette façon : une fonction est un objet qui s'évalue selon sa définition ; les paramètres par défaut sont une sorte de "données membres", leur état peut donc changer d'un appel à un autre - avec n'importe quel autre. l'objet est exactement le même.
Quoi qu'il en soit, effbot (Fredrik Lundh) a une bonne explication de la raison de ce comportement dans Valeurs des paramètres par défaut en Python. Je l’ai trouvé très clair et je recommande vraiment de le lire pour mieux comprendre le fonctionnement des objets fonction.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!