IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Explication fonctionnement boucle + lambda


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Par défaut Explication fonctionnement boucle + lambda
    Bonjour,
    je m'arrache les cheveux sur le problème ci-dessous.
    Est ce que quelqu'un peut m'expliquer :
    1-pourquoi ça ne fonctionne pas?
    2-quelle est la solution?

    Voici mon script:
    from tkinter import *

    fen=Tk()
    liste=[]
    for i in range (5):
    ___liste.append(IntVar())
    ___liste[i].set(i)
    ___Button(fen, textvariable=liste[i], command = lambda : print("Vous avez appuyé sur le bouton",liste[i].get())).pack()
    fen.mainloop()

    La "même chose" mais qui fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from tkinter import *
     
    fen=Tk()
    liste=[]
    for i in range (5):
       liste.append(IntVar())
       liste[i].set(i)
    Button(fen, textvariable=liste[0], command = lambda : print("Vous avez appuyé sur le bouton",liste[0].get())).pack()
    Button(fen, textvariable=liste[1], command = lambda : print("Vous avez appuyé sur le bouton",liste[1].get())).pack()
    Button(fen, textvariable=liste[2], command = lambda : print("Vous avez appuyé sur le bouton",liste[2].get())).pack()
    Button(fen, textvariable=liste[3], command = lambda : print("Vous avez appuyé sur le bouton",liste[3].get())).pack()
    Button(fen, textvariable=liste[4], command = lambda : print("Vous avez appuyé sur le bouton",liste[4].get())).pack()
    fen.mainloop()
    Merci par avance!
    PS: évidemment avec les bonnes indentations!

  2. #2
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    !


    il faut garder en référence i : lambda i=i: print(.....)Sinon je comprends pas le délire de liste[i].get() et avec tout le reste d'ailleurs ..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from tkinter import *
     
    fen=Tk()
    for i in range(5):
        Button(fen, text=i, command=lambda i=i : print("Vous avez appuyé sur le bouton", i)).pack()
        # ou avec les F strings
        Button(fen, text=i, command=lambda i=i : print("Vous avez appuyé sur le bouton {}".format(i))).pack()
        Button(fen, text=i, command=lambda i=i : print(f"Vous avez appuyé sur le bouton {i}")).pack() #disponible depuis 3.6
     
    fen.mainloop()

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    Salut,

    Lancez l'interpréteur Python. Si on écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> def f(): print(x)
    ...
    >>> f()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 1, in f
    NameError: name 'x' is not defined
    >>> x = 3
    >>> f()
    3
    >>>
    La fonction affichera la dernière valeur assignée à x...
    Et si x est mon indice de boucle ce sera pareil.
    Donc déjà il faut ajouter un paramètre à f pour qu'elle soit appelée avec le "bon" x.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> def f(x): print (x)
    ...
    >>> f(x=1)
    1
    >>> f(x=2)
    2
    >>>
    Après il faut ajouter l'effet "lambda" i.e. on fabrique une fonction à la volée dont le paramètre d'appel sera la valeur du "x" lors de sa création:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> f = lambda x=x: print(x)
    >>> f()
    3
    Et si "x" change:
    on obtient toujours la même chose car le "bon" x a été gelé dans les paramètres par défaut.

    - W
    >>>
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Par défaut
    Merci pour votre aide!

    la subtilité du i=i pour que ça fonctionne m'échappe mais bon j'essayerais de m'en souvenir dans le cas de boucles.

    le délire de liste[i].get() vient du fait que je voulais récupérer le texte du bouton (qui là sont des nombres de 0 à 4 mais dans une autre version pourrait être n'importe quoi)
    et comme dans textvariable je ne peux mettre qu'un XXXVar() il me semblait qu'il fallait utiliser un .get() pour récupérer son contenu.

    Encore ne fois merci!

  5. #5
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    Citation Envoyé par mg33bx Voir le message
    Merci pour votre aide!

    la subtilité du i=i pour que ça fonctionne m'échappe mais bon j'essayerais de m'en souvenir dans le cas de boucles.

    le délire de liste[i].get() vient du fait que je voulais récupérer le texte du bouton (qui là sont des nombres de 0 à 4 mais dans une autre version pourrait être n'importe quoi)
    et comme dans textvariable je ne peux mettre qu'un XXXVar() il me semblait qu'il fallait utiliser un .get() pour récupérer son contenu.

    Encore ne fois merci!
    Si tu dit text=i et que t'as lambda i=i: print("blablabla", i) est-ce que ça reviendrait pas au même, mais en plus simple non ?

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Par défaut
    Citation Envoyé par flapili Voir le message
    Si tu dit text=i et que t'as lambda i=i: print("blablabla", i) est-ce que ça reviendrait pas au même, mais en plus simple non ?
    Oui c'est plus simple et équivalent pour ce petit bout de code mais, ce n'est pas ce que je voulais faire par la suite, je veux être capable de modifier l'affichage du bouton par une autre action. Par contre là où je suis bloqué c'est que l'action sur un bouton lui reste "figé".

    Voilà où j'en suis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    from tkinter import *
     
    listeNom=[]
     
    Fenetre=Tk()
    Fenetre.title("Titre")
    Fenetre.geometry("200x200")
     
    def affichage(var_fonction):
       print("Vous avez cliqué sur le bouton ", var_fonction)
     
    for var_boucle in range(5):
       listeNom.append(IntVar())
       listeNom[var_boucle].set(var_boucle+1)
       Button(Fenetre, textvariable=listeNom[var_boucle],command=lambda var_lambda=listeNom[var_boucle].get():affichage(var_lambda)).pack()
     
    Button(Fenetre, text="Test",command=lambda :listeNom[3].set(42)).pack()
    #il ne reste "plus qu'à" faire en sorte que quand j'appuie sur le "Bouton 3" ça affiche "Vous avez cliqué sur le bouton 42"
    Fenetre.mainloop()

  7. #7
    Membre chevronné
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    514
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 514
    Par défaut
    pas de balise code pas d'aide!

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Mai 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Mai 2018
    Messages : 4
    Par défaut
    Citation Envoyé par flapili Voir le message
    pas de balise code pas d'aide!
    Désolé pour les balises, je ne connaissais pas, j'ai modifié mon message en conséquence.

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 715
    Par défaut
    Salut,

    Ecrire lambda var_lambda=listeNom[var_boucle].get():affichage(var_lambda) c'est bien compliqué pour faire lambda var_lambda=var_boucle+1:affichage(var_lambda).
    Vous avez ici un bon tuto sur les "closures"/fermetures.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. [Batch] Fonctionnement boucle for
    Par blanquettedeveau dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 04/07/2016, 10h20
  2. Explication fonctionnement application
    Par totot dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 10/06/2014, 21h34
  3. Faire fonctionner les Lambdas
    Par hyrulia dans le forum Android
    Réponses: 0
    Dernier message: 28/03/2014, 10h58
  4. explication fonctionnement fonction
    Par bergoliv dans le forum C++
    Réponses: 5
    Dernier message: 20/01/2009, 19h53
  5. demande explication sur boucle "FOR"
    Par maori dans le forum Général Python
    Réponses: 4
    Dernier message: 02/01/2009, 17h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo