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 :

Nom d'une variable


Sujet :

Python

  1. #1
    Membre éprouvé

    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
    Par défaut Nom d'une variable
    Bonsoir,
    le code suivant permet dans certains cas de retrouver les noms possibles d'une variable.

    Le code plante dans le cas de oneVar . Avez-vous des idées pour améliorer cela ?

    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
    32
    import gc
    import sys
     
    def name(obj):
        """
        Source : http://pythonic.pocoo.org/2009/5/30/finding-objects-names
        """
        frame = sys._getframe()
     
        for frame in iter(lambda: frame.f_back, None):
            frame.f_locals
     
        result = []
     
        for referrer in gc.get_referrers(obj):
            if isinstance(referrer, dict):
                for k, v in referrer.items():
                    if v is obj:
                        result.append(k)
        return result
     
    # Bon
    oneDict = {'2': None}
    print(name(oneDict))
     
    # Bon
    oneList = ['2', None]
    print(name(oneList))
     
    # Pas bon car inutilisable
    oneVar = 4
    print(name(oneVar))

  2. #2
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    Le code "plante" c'est à dire?
    Win7-64 bits
    - Py27 - Ok
    - Py32 - Ok (avec plus de vars)

    mais je ne comprend pas vraiment de quoi il est question
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  3. #3
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    J'ai rien dit
    je pense que le code est Ok.
    Vu que les entiers/chaines dans un certain ordre sont les meme(id), c'est normal qu'il ressorte tous les éléments pour une valeur int(str aussi je pense) donnée.
    vu qu'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a=4
    b = int(a)
    d = 2+2
    #est equivalent a:
    a=b=d=4
    alors je coche "validé"
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  4. #4
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    Une question, en le faisant via les dicts globals()/locals() ca ne le ferait pas?
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  5. #5
    Membre éprouvé

    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
    Par défaut
    Bonjour afranck64.

    Le script renvoie sur mon Mac :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ['oneDict']
    ['oneList']
    ['LC_NUMERIC', 'T_FMT_AMPM', 'LC_NUMERIC', 'T_FMT_AMPM', 'LC_NUMERIC',
    'T_FMT_AMPM', 'DEBUG_UNCOLLECTABLE', 'DEBUG_UNCOLLECTABLE', 'SIGILL',
    'SIGILL', 'oneVar', 'R_OK', 'O_NONBLOCK', 'O_NDELAY', 'EINTR', 'EINTR',
    'R_OK', 'O_NONBLOCK', 'O_NDELAY', 'R_OK', 'O_NONBLOCK', 'O_NDELAY',
    'ST_UID', 'UF_APPEND', 'S_IROTH', '_abc_negative_cache_version', 'NEWLINE',
    'LOCALE', 'L', 'SRE_INFO_CHARSET', 'SRE_FLAG_LOCALE',
    'SRE_INFO_CHARSET', 'SRE_FLAG_LOCALE', 'SRE_INFO_CHARSET',
    'SRE_FLAG_LOCALE', 'NEWLINE']
    La dernière liste n'est pas ce qui est attendu.

    Une question, en le faisant via les dicts globals()/locals() ca ne le ferait pas?
    Tu penses à quoi. Le script doit marcher y compris lorsqu'il est appelé depuis un autre fichier via un import.

  6. #6
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Je pense que le problème vient du fait que les types “simples“ de python, comme les nombres, sont immutables (cf. http://docs.python.org/py3k/referenc...type-hierarchy), et que donc toutes les variables valant 4 utilisent le même objet*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> a = 4
    >>> b = 8-4
    >>> a is b
    True
    >>> id(a)
    9296064
    >>> id(b)
    9296064
    Donc, rien à faire dans ces cas-là (les int, float, str, etc.), amha.

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 651
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 651
    Par défaut
    Bonjour mont29,

    Donc, rien à faire dans ces cas-là (les int, float, str, etc.), amha.
    je ne suis pas sûr pour les float

  8. #8
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Hmm… Oui, effectivement, les float ne sont pas concernés…

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> a = 4.0
    >>> b = 4.0
    >>> a is b
    False
    >>> id(a)
    28433664
    >>> id(b)
    28433760

  9. #9
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    @rambc ah non, dans ce cas, via globals() il faudra soi-même se taper la récursion sur les modules. et ca serait probablement plus lourd

    bref, je crois qu'on est tous d'accord sur le point que le code est OK
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  10. #10
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut
    Bonjour,

    En ce qui concerne les strings, la comparaison doit se faire avec == et non avec <is> (ligne 18 du code original). Le test suivant me semble plus bulletproof:

  11. #11
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par VV33D Voir le message
    Bonjour,

    En ce qui concerne les strings, la comparaison doit se faire avec == et non avec <is> (ligne 18 du code original). Le test suivant me semble plus bulletproof:
    id(v) == id(obj) équivaut à v is obj.
    Les strings sont immutables (comme les int) mais contrairement aux "int", Python n'associera pas toujours le même objet pour deux strings égales au sens '=='. Après la question est de savoir si on cherche l'ensemble des chemins qui font référence à un objet donné dans une logique gestion mémoire, ou si on cherche les références à des objets égaux mais pas toujours identiques.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Membre éprouvé

    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
    Par défaut
    Merci pour les compléments.

    Je suis donc arriver à la méthode suivante qui me convient parfaitement. Il peut sembler un peu lourdingue de taper name(oneStrVar, globals().keys()) mais cela a le mérite d'être utilisable n'importe où via un import.

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    import gc
    import sys
     
    def name(obj, globalsKeys):
        frame = sys._getframe()
     
        for frame in iter(lambda: frame.f_back, None):
            frame.f_locals
     
        result = []
     
        for referrer in gc.get_referrers(obj):
            if isinstance(referrer, dict):
                for k, v in referrer.items():
                    if v is obj:
                        result.append(k)
     
        if type(obj) == int:
            result = [x for x in globalsKeys if x in result]
     
        return result
     
    # Exemples
    oneDict = {'2': None}
    print(
        "oneDict = {'2': None}",
        name(oneDict, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneList = ['2', None]
    print(
        "oneList = ['2', None]",
        name(oneList, globals().keys()),
        '---',
        sep = "\n"
    )
     
    anotherList = oneList
    print(
        "anotherList = oneList",
        name(anotherList, globals().keys()),
        '---',
        sep = "\n"
    )
     
    print(
        "Z!!! oneList  after  anotherList",
        name(oneList, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneFloat = 4.0
    print(
        "oneFloat = 4.0",
        name(oneFloat, globals().keys()),
        '---',
        sep = "\n"
    )
     
     
    class oneClass():
        def __init__(self):
            self.dico = {'2': None}
     
    print(
        "oneClass",
        name(oneClass, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneInstance = oneClass()
    print(
        "oneInstance = oneClass()",
        name(oneInstance, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneDicoAtt = oneInstance.dico
    print(
        "oneDicoAtt = oneInstance.dico",
        name(oneDicoAtt, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneStr = '5'
    print(
        "oneStr = '5'",
        name(oneStr, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneVar = 2
    print(
        "oneVar = 2",
        name(oneVar, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneVar = 5
    print(
        "oneVar = 5",
        name(oneVar, globals().keys()),
        '---',
        sep = "\n"
    )
     
    anotherVar = 5
    print(
        "anotherVar = 5",
        name(anotherVar, globals().keys()),
        '---',
        sep = "\n"
    )
     
    lastVar = 6
    print(
        "lastVar = 6",
        name(lastVar, globals().keys()),
        '---',
        sep = "\n"
    )
     
    oneStrVar = int(str(oneVar))
    print(
        "Z!!! oneStrVar = int(str(oneVar))",
        name(oneStrVar, globals().keys()),
        '---',
        sep = "\n"
    )
    On obtient comme attendu ou presque ce qui suit. Au passage, ce programme est à mon avis un bon support pour expliquer les problèmes liés aux copies de listes et de dictionnaires par exemple.
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    oneDict = {'2': None}
    ['oneDict']
    ---
    oneList = ['2', None]
    ['oneList']
    ---
    anotherList = oneList
    ['anotherList', 'oneList']
    ---
    oneList  after  anotherList
    ['anotherList', 'oneList']
    ---
    oneFloat = 4.0
    ['oneFloat']
    ---
    oneClass
    ['oneClass']
    ---
    oneInstance = oneClass()
    ['oneInstance']
    ---
    oneDicoAtt = oneInstance.dico
    ['dico', 'oneDicoAtt']
    ---
    oneStr = '5'
    ['oneStr']
    ---
    oneVar = 2
    ['oneVar']
    ---
    oneVar = 5
    ['oneVar']
    ---
    anotherVar = 5
    ['anotherVar', 'oneVar']
    ---
    lastVar = 6
    ['lastVar']
    ---
    oneStrVar = int(str(oneVar))
    ['oneStrVar', 'anotherVar', 'oneVar']
    ---
    MacBook-Pro-de-cbal:~ cbal$ python3 /Users/cbal/Documents/bazar/test.py 
    oneDict = {'2': None}
    ['oneDict']
    ---
    oneList = ['2', None]
    ['oneList']
    ---
    anotherList = oneList
    ['anotherList', 'oneList']
    ---
    Z!!! oneList  after  anotherList
    ['anotherList', 'oneList']
    ---
    oneFloat = 4.0
    ['oneFloat']
    ---
    oneClass
    ['oneClass']
    ---
    oneInstance = oneClass()
    ['oneInstance']
    ---
    oneDicoAtt = oneInstance.dico
    ['dico', 'oneDicoAtt']
    ---
    oneStr = '5'
    ['oneStr']
    ---
    oneVar = 2
    ['oneVar']
    ---
    oneVar = 5
    ['oneVar']
    ---
    anotherVar = 5
    ['anotherVar', 'oneVar']
    ---
    lastVar = 6
    ['lastVar']
    ---
    Z!!! oneStrVar = int(str(oneVar))
    ['oneStrVar', 'anotherVar', 'oneVar']
    ---

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

Discussions similaires

  1. Module dont le nom est une variable
    Par Mr Hyde dans le forum Général Python
    Réponses: 11
    Dernier message: 26/02/2023, 21h39
  2. [Tableaux] Concaténation du nom d'une variable
    Par nebule dans le forum Langage
    Réponses: 11
    Dernier message: 18/05/2006, 12h30
  3. Réponses: 37
    Dernier message: 02/03/2006, 02h58
  4. Incrémenter le NOM d'une variable
    Par Mors_Ubyte dans le forum Access
    Réponses: 1
    Dernier message: 03/01/2006, 19h47
  5. [Reflection] Connaître le nom d'une variable ...
    Par dahwoud dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 09/08/2005, 15h37

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