Function en argument - signification de lambda

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J’aimerais avoir des éclaircissement sur l’utilité et la signification d’ajouter lambda: quand certaines fonctions sont utilisées en paramètre d’autres fonctions.

Je pense au code trouvé ici dans lequel les fonctions whichbtn et btnstate sont très similaires, avec l’exception que l’une d’entre-elles a un paramètre d’entrée. L’appel dans le clicked.connect diffère par un lambda:, et malgré l’explication quelques lignes plus haut, je ne saisis pas bien ce que ca fait et veut dire.

J’ai eu le même soucis dans mon code, avec la même solution que je ne comprends pas.

class AddSentence(Main):
    fieldsY=100
    fieldsX=100
    fieldWidth=850
    def setUI(self):
        super().setUI()
        self.translationField=QLineEdit(self)
        self.translationField.move(self.fieldsX,self.fieldsY)
        self.translationField.resize(self.fieldWidth,50)
        self.translationOK=QPushButton("Valider",self)
        self.translationOK.move(self.fieldsX+self.fieldWidth+50,self.fieldsY)
        self.translationOK.resize(100,50)
        self.translationOK.clicked.connect(lambda: self.onClickedValider(self.translationField))

    def setUIList(self):
        pass

    def onClickedValider(self,translationField):
        sentenceList.append(translationField.text())
        translationField.setText("")
        self.setUIList()
        self.update()

Sans ce lambda:, je me prends une erreur TypeError: argument 1 has unexpected type 'NoneType'.

J’ai cherché un peu sur mon moteur de recherche préféré, mais je ne trouve que des explications sur comment définir une fonction en utilisant le mot clé lambda, rien qui ne se rapproche de ce cas-ci.

Merci d’avance !

Cette réponse a aidé l’auteur du sujet

J’espère ne pas dire de bêtises (je ne code pas trop).

Si tu écris self.translationOK.clicked.connect(self.onClickedValider(self.translationField)) alors tu es en train d’appeler self.translationOK.clicked.connect avec comme argument le résultat de self.onClickedValider(self.translationField). Cette dernière fonction ne renvoie sûrement rien, d’où le 'NoneType’.

En ajoutant le lambda, tu passes en argument une fonction dont le code est simplement self.onClickedValider(self.translationField).

Dans le cas sans argument, je pense que si tu appelles clicked.connect avec btnstate() alors tu as aussi un problème car tu passes en argument le résultat de la fonction (les parenthèses font que la fonction est appelée).

Pour résumer, tu peux faire :

clicked.connect(btnstate)
#ou bien
clicked.connect(lambda : btnstate())
+4 -0
Auteur du sujet

Je me permets de reposter. J’ai bien compris l’utilité de lambda dans ce cas précis, mais il me semble que c’est un peu du bricolage : utiliser lambda pour définir une fonction déjà définie par ailleurs. Y a-t-il une autre manière plus "propre" pour indiquer que l’on veut utiliser la fonction avec un argument plutôt que son résultat ?

Cela dit, construire une fonction partielle en lui passant en fait tous ses arguments ne donne pas un message très clair sur ce qui se passe. Je serais d’avis de conserver lambda, c’est pas du bricolage, ce mot clé existe spécifiquement pour construire des fonctions plutôt simples à la volée. On voit tout de suite ce que lambda: f(x) fait: construire une fonction ne prenant pas d’argument et dont le corps est f(x). Par contre, avec functools.partial(f, x), on sait pas trop ce qu’on obtient comme fonction et il faut aller voir f pour savoir quel argument elle attend.

Édité par adri1

I don’t mind that you think slowly, but I do mind that you are publishing faster. — W. Pauli

+2 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte