Quelqu'un bricolage avec Python assez longtemps a été mordu (ou déchiré) par le problème suivant:
def foo(a=[]):
a.append(5)
return a
Python novices attendre cette fonction retourne toujours une liste avec un seul élément: [5]
. Le résultat est plutôt très différents, et très étonnant (pour un débutant):
>>> foo()
[5]
>>> foo()
[5, 5]
>>> foo()
[5, 5, 5]
>>> foo()
[5, 5, 5, 5]
>>> foo()
Un gestionnaire de la mine une fois eu sa première rencontre avec cette fonctionnalité, et l'a appelé "une dramatique défaut de conception" de la langue. J'ai répondu que le comportement a eu une explication, et il est en effet très surprenant et inattendu si vous ne comprenez pas le fonctionnement interne. Cependant, je n'étais pas en mesure de répondre (pour moi) à la question suivante: quelle est la raison de la liaison de l'argument par défaut à la définition de la fonction, et non à l'exécution de la fonction? Je doute que les expérimentés comportement a une utilisation pratique (qui a vraiment utilisé les variables statiques en C, sans reproduction des bugs ?)
Edit:
Baczek fait un exemple intéressant. Avec la plupart de vos commentaires et Utaal en particulier, j'ai précisé:
>>> def a():
... print "a executed"
... return []
...
>>>
>>> def b(x=a()):
... x.append(5)
... print x
...
a executed
>>> b()
[5]
>>> b()
[5, 5]
Pour moi, il semble que la décision a été par rapport à l'endroit où placer la portée de paramètres: l'intérieur de la fonction ou "ensemble"?
Faire la liaison à l'intérieur de la fonction signifierait qu' x
est effectivement lié à la valeur par défaut lorsque la fonction est appelée, ne sont pas définis, ce qui permettrait de présenter une profonde faille: l' def
ligne serait "hybride" dans le sens qu'une partie de la liaison (de la fonction de l'objet) arriverait-il à la définition, et la partie (affectation de paramètres par défaut) lors de l'invocation de la fonction de temps.
Le comportement réel est plus cohérent: tout de qui ligne est évaluée lorsque cette ligne est exécutée, un sens à la définition de la fonction.
Guido est un designer fantastique.
Modifier
J'ai relu toutes les très intéressantes et de bonnes réponses que vous avez fournies, et il est difficile d'attribuer une "correcte tickmark", que tout le monde avait de bons points dans la réponse. J'ai marqué Roberto réponse comme correcte parce que c'était plus simple et de révéler, de sorte que les nouveaux arrivants de la navigation à cette question peut commencer à partir de sa réponse et se plonger dans l'autre plus complexe (mais très perspicace) des réponses.