références Confondre à l'objet même (mutable) avec des références à des objets séparés est en effet un " gotcha "(subi par tous les langages non fonctionnels, ceux qui ont des objets mutables et, bien sûr, des références). Un bug souvent vu dans le code Python débutants utilise à mauvais escient une valeur par défaut qui est mutable, par exemple:
def addone(item, alist=[]):
alist.append(item)
return alist
Ce code peut être correct si le but est d'avoir addone
garder son propre état (et le retour d'une liste croissante aux appels successifs), autant que les données static
fonctionneraient en C; ce n'est pas correct si le codeur suppose à tort qu'une nouvelle liste vide sera faite à chaque appel.
La décision de conception command-query separation dans les conteneurs intégrés de Python peut également perturber les débutants bruts utilisés dans les langages fonctionnels: les méthodes de mutations qui n'ont rien à renvoyer (la grande majorité des méthodes de mutation) ne retournent rien (en particulier, ils retournent None
) - ils font tout leur travail "sur place". Les bogues provenant d'un malentendu sont faciles à repérer, par ex.
alist = alist.append(item)
est à peu près garanti d'être un bug - il ajoute un élément à la liste mentionnée par nom alist
, mais reliaisons puis le nom alist
-None
(la valeur de retour de l'appel append
). Alors que le premier problème que j'ai mentionné concerne une liaison précoce qui peut tromper les gens qui pensent que la liaison est plutôt tardive, il y a des problèmes qui vont dans l'autre sens, où les attentes de certaines personnes sont pour une liaison précoce. tandis que la reliure est plutôt en retard. Par exemple (avec un cadre graphique hypothétique ...):
for i in range(10):
Button(text="Button #%s" % i,
click=lambda: say("I'm #%s!" % i))
cela montrera dix boutons disant « Bouton # 0 », « Bouton # 1 », etc, mais, quand on clique dessus, chacun des ils c'est #9
- parce que le i
dans le lambda
est lié tardivement (avec une fermeture lexicale). Un correctif est de tirer profit du fait que les valeurs par défaut pour l'argument sont précoce liés (comme je l'ai souligné au sujet de la première question -) et changer la dernière ligne
click=lambda i=i: say("I'm #%s!" % i))
Maintenant lambda
« s i
est un argument avec une valeur par défaut, pas une variable libre (recherchée par fermeture lexicale), et donc le code fonctionne comme prévu (il y a d'autres façons, bien sûr).
Ce fut la principale Gotcha pour moi de passer à Python, mais je pense qu'il est aussi un Gotcha commun pour les personnes qui commencent à utiliser Python sans avoir utilisé Matlab avant. Je pourrais toutefois avoir tord. –
En relation: http://zephyrfalcon.org/labs/python_pitfalls.html http://www.ferg.org/projects/python_gotchas.html – jfs