Bonsoir,
Étant poussé à la faire, je relance ici dans une file en propre une interrogation que j’ai depuis longtemps mais qui s’est activée un peu plus fort à l’occasion d’une belle réponse de dividee dans le message suivant:
http://www.developpez.net/forums/d90...e/#post5134761
et dont voici la majeure partie:
POST DE DIVIDEE:
le problème [est] lié à l'utilisation de lambda. Le code contenu dans l'expression lambda n'est pas évalué immédiatement mais uniquement lorsque la fonction retournée par l'expression lambda est appelée. Donc la valeur de file à l'exécution de la lambda est sa valeur au point d'appel, pas au point de définition (idem pour a dans le code de airod).
Le code ci-dessous illustre également ceci:
La solution "pythonesque" est liée à une autre caractéristique de python: les valeurs par défaut des arguments d'une fonction sont évalués à la définition, pas à l'appel.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 >>> l = [1,2,3]>>> m = [lambda:e for e in l] >>> m [<function <lambda> at 0x00EF5830>, <function <lambda> at 0x00EF5770>, <function <lambda> at 0x00EF57B0>] >>> m[0]() 3 >>> del e >>> m[0]() Traceback (most recent call last): File "<interactive input>", line 1, in <module> File "<interactive input>", line 1, in <lambda> NameError: global name 'e' is not defined
C'est d'ailleurs un autre piège de Python: si on donne un objet mutable comme valeur par défaut d'un argument, on risque des surprises:
[ ...se reporter au message pour cette partie de discussion...]
Mais pour le problème qui nous occupe, on va exploiter ce fait:
Il est idiomatique en Python d'écrire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 >>> m = [lambda x=e:x for e in l] >>> m[0]() 1 >>> m[1]() 2
qui revient au même mais cela peut troubler si on ne l'a jamais vu.
Code : Sélectionner tout - Visualiser dans une fenêtre à part m = [lambda e=e:e for e in l]
On a certes une lambda avec un argument à présent, mais comme cet argument possède une valeur par défaut, on peut toujours l'appeler de la même façon.
FIN DU POST DE DIVIDEE
-----------------------------------------------------------
Et voilà ma question brouillone:
@ dividee
Tes deux messages et leurs explications m’ont laissé pantois.
Comme je n’aime pas trop les fonctions lambda, j’ai déjà eu du mal à comprendre la signification de l’expression [lambda:e for e in l]
Tout le reste, qui est passionant, m’a aussi demandé pas mal de phosphoration.
Mais j’avoue que je garde le sentiment de ne pas avoir tout bien bien compris.
Mon problème est que j’aime bien, ou j’ai besoin, de saisir ce qui se passe derrière les expressions, en coulisse du code textuel, au niveau de l’implémentation, savoir quels sont les objets, et les processus qui les affectent, qui sont en cause.
Or, à mon avis, ce dont tu parles a à voir avec des caractères fondamentaux de l’implémentation de Python, au niveau de la construction des objets et des processus dans lesquels sont impliqués des arguments.
Aussi cela m’intéresserait d’avoir tes éclaircissements sur un point qui n’est pas clair pour moi. Pas seulement dans ton post, d’une façon générale dans les docs. Mais comme tu en parles dans ton post, et avant de le laisser disparaître dans les profondeurs des pages >1 comme d’autres, je demande, toute honte bue:
que recouvre exactement le terme “évaluer“ ?
Le code contenu dans l'expression lambda n'est pas évalué immédiatement mais uniquement lorsque la fonction retournée par l'expression lambda est appelée.
La solution "pythonesque" est liée à une autre caractéristique de python: les valeurs par défaut des arguments d'une fonction sont évalués à la définition, pas à l'appel.
Il me semble qu’avnt de faire une exécution d’un programme, il y a une phase dans laquelle le texte du code est examiné (est-ce ce qu’on appelle analyse syntaxique ? est-ce l’interprétation ? par quoi est- ce fait, l’interpréteur ?... mystères opaques pour moi) pour établir un tas de trucs: espaces de noms, qualité de locale ou globale pour une variable... etc... je crois, je n’ai rien trouvé de précis sur ces aspects, ou je n’ai pas su trouver. Enfin bref.
Ce que je veux dire, c’est que j’imagine que c’est dans cette phase préalable que se situe ce que tu appelles “définition“ et que c’est à cette phase que se réfère le terme “immédiatement“.
Donc, dans ce que tu as écrit, je distingue deux sortes de moments, c’est à dire d’événements: les moments où quelque chose est défini, le moment où quelque chose est appelé.
Ce quelque chose est-il toujours un objet ?
Est-ce que “définition“ signifie “création d’un objet“.
Est-ce que tu es d’accord avec l’idée que je me fais d’une création d’objet: délimitation d’une zone mémoire par une sorte de cloture qui consiste en je ne sais quoi et oganisation des bits à l’intérieur de cette zône pour la rendre apte à représenter une structure logique donnée ?
Est-ce que “évaluer“ est synonyme de “définition“ et/ou “création d’objet“ ?
La question sollicite d’ailleurs tout un chacun qui aurait eu des aperçus au travers des brumes sur les processus concernés dans ce que je pense ètre ce qu’on appelle implémentation.
Merci
Partager