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 :

comment récupérer le nom d'une variable autre que d'une fonction ou d'une classe


Sujet :

Python

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut comment récupérer le nom d'une variable autre que d'une fonction ou d'une classe
    Bonjour
    Je voudrais savoir comment récupérer le nom d'une variable autre que d'une fonction ou d'une classe.
    Question simple surement mais après plusieurs recherches je ne n'ai pas trouvé.
    J'ai surement du passer à côté de la réponse, mais bon ........
    J'ai identifié pour les class méthode et fonction la solution c'est
    par exemple
    def mafonction(var):
    pass
    Ensuite print mafonction.__name__ donne bien le nom attendu

    Le champ de ma question est :

    essai='valeur essai'

    def nom_param(var):
    zone à completer.....
    return nom
    print nom_param(essai) doit retourner la chaine 'essai'

    question subsidiaire
    à l'intérieur d'une méthode d'une classe j'ai défini la variable self.variable
    je m'attends à ce que def val_param me retourne variable alors que je voudrai la valeur 'self.variable'
    il y t-il une astuce complémentaire pour traiter ce point automatiquement ?

    Merci d'avance de votre aide

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonjour,

    je peux me tromper mais je ne pense pas que cela soit possible. le "nom" de la variable n'est pas transmis à la fonction car il ne fait pas partie de la variable.

    quel problème te pousses à poser cette question ? il est possible que tu sois en train de passer à côté de quelquechose

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Bonjour
    Mon besoin initial est quand je fais du developpement j'ai besoin d'une fonction simple pour afficher le nom d'une variable et sa valeur

    par exemple

    variable= 'toto'
    printv (variable)

    printv doit m'afficher
    variable à la valeur toto

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 059
    Points : 1 396
    Points
    1 396
    Par défaut
    un truc crade ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def foo(var):
        print globals()[var],'--->',var
     
    nom1 = 'toto'
    foo('nom1')

  5. #5
    Membre habitué Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Points : 190
    Points
    190
    Par défaut
    josmiley, je pense que ta solution "crade" ne convient pas...
    Ce que veut turboiii c'est foo(nom1) et non pas foo('nom1').
    Dis moi si je me trompe turboiii...

    Je pense que le truc qui va bien c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def var_name(var):
        for name,value in globals().items() :
            if value is var :
                return name
        return '?????' 
     
    def printv ( var ):
        print var_name( var ),'=',var
     
    nom1 = 132
    printv( nom1 )
    qui affiche bien "nom1 = 132".

  6. #6
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 751
    Points
    1 751
    Par défaut
    Bonjour.

    Cette méthode n'est pas parfaite comme le montre l'exemple suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    nom1 = 132
    printv( nom1 )
     
    nom2 = nom1
    printv( nom1 )
     
    nom2 = "a"
    printv( nom1 )
    Ceci renvoie chez moi sous Python 3 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    nom1 = 132
    nom2 = 132
    nom1 = 132

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Ci-dessous le code que j'ai testé
    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
    def var_name(var):
        for name,value in globals().items() :
            if value is var :
                return name
        return '?????' 
     
    def printv ( var ):
        print var_name( var ),'=',var
     
    nom1 = 132
    printv( nom1 )
     
    nom2 = nom1
    printv( nom2 )
     
    nom2 = "a"
    printv( nom2 )
    ce qui donne bien
    nom1 = 132
    nom2 = 132
    nom2 = a
    chez moi sa fonctionne bien c'est bien conforme à ma demande bravo les gars
    Il doit y avoir une coquille sur le 3eme printv( nom2 )
    je teste cela dans mon projet......

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Bon de retour de test. Effectivement cela fonctionne bien pour des variables globales puisqu'on cherche dans le dictionnaire des variables globales.
    Toutefois comme je m'y attendais cela ne fonctionne plus lorsque c'est utilisé avec des variables dont la portée est locale et dans une méthode ou une procedure....

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Bon j'ai fait de nouveau test avec une petite amélioration pour gérer le cas des variables locales. Cela complique un peu la fonction mais à peine.

    Un léger inconvénient le texte à copier pour chaque essai est plus long
    Je vais utiliser le copier coller un peu plus souvent

    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
     
    def var_name(var,dico):
        """
        cherche le nom d'une variable à partir de globals() si dico == None
        sinon cherche dans le dico de variable locale passé en paramètre
        """
        if dico == None:
            for name,value in globals().items() :
                if value is var :
                    return name
        else:
            for name,value in dico.items() :
                if value is var :
                    return name
        return u'????? nom de variable non trouvé' 
     
    def printv ( var,dico = None ):
        """ édite à la console le nom et la valeur d'une variable globale
        si la variable est locale obligation de passer le dictionnaire des variables locales de la portée de nom considérée c'est le locals()
        exemple 
        printv (ui,locals()) cherche a éditer la variable ui dans le dictionnaire passé en paramètre
        """
        print var_name( var,dico ),' = ',var
    Dans l'état je considère que le résultat est pas mal et résolu .
    Si toutefois quelqu'un à mieux à proposer bien sur je suis preneur

    pour une variable globale je mets la ligne de code suivante
    printv ( constructeur)
    pour une variable locale je mets la ligne de code suivante
    printv ( constructeur,locals())

    l'usage par copier coller sera assez simple même pour le cas des variables locale, ce qui représente la majorité des cas pour moi.
    Je vais m'en servir pour tester l'état de mes variables pour débugguer mon code.
    Merci à tous

  10. #10
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 751
    Points
    1 751
    Par défaut
    Cette version ne corrige pas le petit souci que j'ai indiqué.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Citation Envoyé par rambc Voir le message
    Cette version ne corrige pas le petit souci que j'ai indiqué.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    nom1 = 132
    printv( nom1 )
     
    nom2 = nom1
    printv( nom1 )
     
    nom2 = "a"
    printv( nom1 )
    je ne vois pas bien le souci. Peux-tu détailler STP ?
    dans ton exemple tu mets 3 X printv (nom1)

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    j'ai fait un nouveau test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    nom1 = 132
    printv( nom1 )
     
    nom2 = nom1
    printv( nom2 )
     
    nom1 = "a"
    print 'après nouvelle affectation de nom1, nom2 ne change pas'
    printv( nom1 )
    printv( nom2 )
    ce qui donne en résultat
    nom1 = 132
    nom2 = 132
    après nouvelle affectation de nom1, nom2 ne change pas
    nom1 = a
    nom2 = 132

    Pour moi c'est normal c'est la logique Python si c'est cela dont tu parles....

  13. #13
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Le problème dont parle rambc est lié au fait que ce code retrouve le nom de la variable en fonction de sa valeur. Si plusieurs variables ont le même valeur, il affichera "au hasard" le nom d'une des variables qui possède cette valeur. "au hasard" parce que les dictionnaires ne sont pas ordonnés.

    Si cela a fonctionné dans ton test, c'est que le hasard a bien fait les choses. Ceci devrait te garantir une mauvaise réponse:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    nom1 = 123
    nom2 = 123
    printv(nom1)
    printv(nom2)
    Il affichera soit deux fois "nom1 = 123" ou deux fois "nom2 = 123".

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Bonjour

    Je suis tout a fait d'accord avec dividee. D'autant plus que j'ai moi même constaté cette anomalie. Pour contrer cette anomalie, j'ai une parade d'un niveau moyen qui consiste à retourner la liste de toute les variables trouvées avec cette valeur.

  15. #15
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Pas trop le temps ce matin mais une autre piste (je vais encore me faire taper sur les doigts avec mes hacks )

    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
    import inspect
     
    def printv ( var ):
        command = str(inspect.stack()[1][4]).split('(')[1].split(')')[0]
        print command, '=', var
     
    nom1 = 132
    printv(nom1)
     
    class foo:
        def __init__(self):
            self.toto='a'
            printv(self.toto)
     
    b=foo()
    Pas le temps de fignoler ou de tester avec sys mais c'est sur le même principe.

    @+

  16. #16
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Citation Envoyé par turboiii Voir le message
    Bonjour
    Mon besoin initial est quand je fais du developpement j'ai besoin d'une fonction simple pour afficher le nom d'une variable et sa valeur

    par exemple

    variable= 'toto'
    printv (variable)

    printv doit m'afficher
    variable à la valeur toto
    hello,

    il me semblait bien qu'en posant la question, tu passais à côté d'un truc
    plutôt que de se faire des nœuds au cerveau pourquoi ne pas utiliser un debugger ? c'est son rôle non ? d'afficher le nom de variables et leurs valeurs.

  17. #17
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Ben oui... Mais c'est moins drôle du coup.

    Bon, puisque j'avais parler de sys :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import sys
    import traceback
     
    def printv (var):
        for Id, Stack in sys._current_frames().items():
            for filename, lineno, name, line in traceback.extract_stack(Stack):
                if 'printv(' in line:
                    print line.replace('printv(', '').replace(')', ''), '=', var
    @+

  18. #18
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Plus simple

    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
    import traceback
     
    def printv (var):
        stack = traceback.extract_stack(limit=2)
        print stack[0][3].replace('printv(', '').replace(')', '')
     
    nom1 = 132
    printv(nom1)
     
    class foo:
        def __init__(self):
            self.toto='a'
            printv(self.toto)
     
    b=foo()
    Mais les deux exemples n'utilisent que le printv bien sur.

    @+

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 147
    Points : 88
    Points
    88
    Par défaut
    Cette fois ci c'est magistralement résolu et c'est net et sans bavure.

    Merci à PauseKawa

  20. #20
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Pas vraiment à vrais dire.
    A partir du moment ou on touche à inspect ou traceback
    ou aux live/frame/code objects c'est plus du hack/debug qu'autre chose.
    Perso je les ranges dans le même dossier que les sys._getframe, setprofile et autres settrace. Soit le dossier: 'This function should be used for internal and specialized purposes only'.
    J'espere que tu auras une réponse plus pythonesque.

    Bon code

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 21
    Dernier message: 18/11/2008, 14h36
  2. Réponses: 3
    Dernier message: 22/07/2008, 10h46
  3. Réponses: 6
    Dernier message: 29/06/2007, 12h43
  4. Réponses: 7
    Dernier message: 26/05/2007, 12h43
  5. Réponses: 11
    Dernier message: 12/05/2006, 17h18

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