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 :

besoin d'une petite explication de la fonction "eval"


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingenieur en mecanique
    Inscrit en
    Juillet 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingenieur en mecanique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2015
    Messages : 4
    Par défaut besoin d'une petite explication de la fonction "eval"
    Bonjour,

    je rencontre actuellement un petit probleme avec la fonction "eval", afin de vous expliquer au mieux voila deux codes minimaliste representant mon probleme:
    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
    # -*- coding: cp1252 -*-
    from Tkinter import *
     
       def fillTheListBox():
     
            listARemplire = "listbox"
            eval(listARemplire).insert(END, "bla bla")
            #listbox.insert(END, "bla bla")
     
     
        Fenetre_02 = Tk()
     
        listbox = Listbox(Fenetre_02, height=15, width=20, font ="Arial 10 bold")
        listbox.pack(side = LEFT, padx = 0, pady = 0)
     
     
        fillTheListBox()
        Fenetre_02.mainloop()
    jusque là ca fonctionne (je pense faire une utiliation correcte de "eval")

    oui mais voila , l'exemple suivant lui ne foncitonne pas et je ne parviens pas a comprendre pourquoi :
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    # -*- coding: cp1252 -*-
    from Tkinter import *
     
     
    def TestDansUneFonction():
     
        def fillTheListBox():
     
            listARemplire = "listbox"
            eval(listARemplire).insert(END, "bla bla")
     
     
        Fenetre_02 = Tk()
     
        listbox = Listbox(Fenetre_02, height=15, width=20, font ="Arial 10 bold")
        listbox.pack(side = LEFT, padx = 0, pady = 0)
     
     
        fillTheListBox()
        Fenetre_02.mainloop()
     
     
     
     
     
    Fenetre_01 = Tk()
     
    Button = Button(Fenetre_01, width=20, text ='Open Fenetre_02', command = TestDansUneFonction)
    Button.pack(side = TOP, padx = 2, pady = 1)
     
    Fenetre_01.mainloop()
    j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1437, in __call__
        return self.func(*args)
      File "/home/bibi/Downloads/test.py", line 20, in TestDansUneFonction
        fillTheListBox()
      File "/home/bibi/Downloads/test.py", line 10, in fillTheListBox
        eval(listARemplire).insert(END, "bla bla")
      File "<string>", line 1, in <module>
    NameError: name 'listbox' is not defined
    je me tourne donc vers vous dans l'espoir de trouver quelqu'un qui puisse m'expliquer où se trouve mon erreur.

    d'avance merci pour votre aide,
    Daan.

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Ça me semble assez simple, dans le premier cas la fonction TestDansUneFonction n'est pas invoquée donc l'erreur n'apparait pas. Mais elle est quand même là.


    jusque là ca fonctionne (je pense faire une utiliation correcte de "eval")
    Non seulement une utilisation incorrecte mais aussi inapropriée.

    Quel est le but de cette fonction ?

    Juste ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    listARemplire = "listbox" + "bla bla"
    Et de plus elle ne retourne rien, alors ... ?

  3. #3
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Après relecture, je pense comprendre que ton intention est ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        def fillTheListBox(widget):
            widget.insert(END, "bla bla")
     
        Fenetre_02 = Tk()
        listbox = Listbox(Fenetre_02, height=15, width=20, font ="Arial 10 bold")
        listbox.pack(side = LEFT, padx = 0, pady = 0)
     
        fillTheListBox(listbox)

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Ingenieur en mecanique
    Inscrit en
    Juillet 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingenieur en mecanique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2015
    Messages : 4
    Par défaut
    Bonjour et merci pour ton aide,

    Mon objectif est bien d'ajouter "bla bla" a la listbox mais le nom de la variable est du type string (le nom de cette variable est généré automatiquement) , j'utilise donc "eval" pour interpréter le string puis j'insert "bla bla" avec " .insert(END, "blabla") "

    Je constat que dans le premier code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(listARemplir).insert(END, "blabla")
    Remplit bien la listbox mais quand je place ce premier code dans une fonction (FillTheListbox) "eval" ne semble plus capable d'interpréter " listARemplir" et je ne comprend pas pourquoi.

    D'après ce que j'ai cru comprendre "eval" devrait me permettre de "convertir " le string en nom de variable.

    J'apprends python par moi-même et je ne suis pas du milieu informatique,
    Il est donc tout a fait possible que j'ai mal compris l'utilisation de " eval" ,
    Dans ce cas pourrai tu m'expliquer ou réside mon erreur ?


    Encore merci pour ton aide,
    Daan

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par DaanNoa Voir le message
    Dans ce cas pourrai tu m'expliquer ou réside mon erreur ?
    Il me semblait avoir répondu.

    Pour reprendre ton code:

    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 *
     
     
    def TestDansUneFonction():
     
        def fillTheListBox():
     
            listARemplire = "listbox"
            eval(listARemplire).insert(END, "bla bla")
     
     
        Fenetre_02 = Tk()
     
        listbox = Listbox(Fenetre_02, height=15, width=20, font ="Arial 10 bold")
        listbox.pack(side = LEFT, padx = 0, pady = 0)
     
     
        fillTheListBox()
        Fenetre_02.mainloop()
    Il génère une erreur, parce qu'à l'intérieur de fillTheListBox, la variable listbox n'existe pas, et elle est nécessaire à eval("listbox") ou à eval(listARemplire) si listARemplire="listbox".

    Solution: soit tu évites les "fonctions de fonction", soit tu transmets la variable listbox comme argument:

    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 *
     
     
    def TestDansUneFonction():
     
        def fillTheListBox(listbox):
     
            listARemplire = "listbox"
            eval(listARemplire).insert(END, "bla bla")
     
     
        Fenetre_02 = Tk()
     
        listbox = Listbox(Fenetre_02, height=15, width=20, font ="Arial 10 bold")
        listbox.pack(side = LEFT, padx = 0, pady = 0)
     
     
        fillTheListBox(listbox)
        Fenetre_02.mainloop()

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Ingenieur en mecanique
    Inscrit en
    Juillet 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingenieur en mecanique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2015
    Messages : 4
    Par défaut
    Re bonjour,

    tyrtamos : tu as répondu pendant que je rédigeais mon message ( j'ai pris un certain temps pour le rédiger )
    Merci pour ta réponse, je vais faire quelques essais pour voir si j'ai bien tout compris.

    Encore merci à vous pour votre aide.

  7. #7
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Ce n'est qu'un problème de visibilité de variable.

    D'abord, print(eval("toto")) n'affiche la valeur de la variable toto que si cette variable a été déclarée avant. A défaut, eval déclenche une erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    toto = 10
    print(eval("toto"))
    10
    Prenons un code simplifié pour voir ce que ça donne dans les fonctions, puis dans les fonctions de fonction:

    Cas d'une fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def fonction():
     
        print("toto" in globals())
        print("toto" in locals())
     
        print(eval("toto"))
     
    toto = 10
    fonction()
    Ce qui affiche:

    Ici, print(eval("toto")) affiche bien 10, parce que dans la fonction, la variable toto est reconnue comme faisant partie des variables globales (dictionnaire globals())

    Cas d'une fonction de fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def fonction():
     
        def fonctiondefonction():
     
            print("toto" in globals())
            print("toto" in locals())
     
            print(eval("toto"))
     
        toto = 10
        fonctiondefonction()
     
    fonction()
    Ce qui affiche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    False
    False
        fonction()
      File "E:\Pythondev\Pydev3_qt5\python3\test99\testC\test05.py", line 13, in fonction
        fonctiondefonction()
      File "E:\Pythondev\Pydev3_qt5\python3\test99\testC\test05.py", line 10, in fonctiondefonction
        print(eval("toto"))
      File "<string>", line 1, in <module>
    NameError: name 'toto' is not defined
    On voit bien que la variable toto n'est ni dans les variables globales, ni dans les variables locales: il y a erreur dans eval.

    Bizarrerie dans les fonctions de fonctions

    Il se passe tout de même des choses bizarres dans les fonctions de fonctions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def fonction():
     
        def fonctiondefonction():
     
            print("toto" in globals())
            print("toto" in locals())
     
        toto = 10
        fonctiondefonction()
     
    fonction()
    Ce qui affiche:

    Donc, comme on l'a vu avant, la variable toto n'est ni dans les variables globales, ni dans les variables locales.

    Petite modification, maintenant: on ajoute seulement un print:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def fonction():
     
        def fonctiondefonction():
     
            print("toto" in globals())
            print("toto" in locals())
     
            print(toto)
     
        toto = 10
        fonctiondefonction()
     
    fonction()
    Logiquement, la variable toto n'ayant pas été déclarée, la tentative de l'affichage de sa valeur devrait déclencher une erreur? Et bien non! Cela affiche:

    C'est à dire que le seul fait de vouloir l'afficher entraine que la variable se trouve maintenant dans les variables locales à la fonction de fonction, et retrouve la valeur déclarée dans la fonction englobante!

    Si quelqu'un peut m'expliquer ça...

    En tout cas, cela explique pourquoi je n'utilise QUASIMENT JAMAIS les "fonctions de fonction" et surtout pas en laissant faire les "effets de bord": c'est pour moi de la mauvaise programmation.

    A l'intérieur d'une fonction, soit la variable fait partie des arguments d'appel, soit elle est déclarée en local. Et j'évite autant que je peux les variables globales.

    Ainsi, si on reprend le code qui déclenchait une erreur et qu'on transmet la variable toto comme argument, il n'y a plus de problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def fonction():
     
        def fonctiondefonction(toto):
     
            print(eval("toto"))
     
        toto = 10
        fonctiondefonction(toto)
     
    fonction()

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2010] Besoin d'une petite explication
    Par onobyone dans le forum Access
    Réponses: 2
    Dernier message: 24/06/2015, 13h07
  2. Besoin d'une petite explication
    Par geforce dans le forum JSF
    Réponses: 1
    Dernier message: 14/02/2012, 08h29
  3. [Command] Besoin d'une petite explication
    Par BkD35 dans le forum Design Patterns
    Réponses: 0
    Dernier message: 26/10/2009, 16h47
  4. Référence, besoin d'une petite explication
    Par sunshine33 dans le forum Langage
    Réponses: 2
    Dernier message: 04/04/2007, 08h00

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