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 :

indirection dans python


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 651
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut indirection dans python
    Bonjour,

    je ne trouve pas d'informations sur la possibilité de faire des indirections, comme en shell
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ v=w
    $ w=foo
    $ echo ${!v}
    foo

    soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >> v = 'foo'
    >> w = 'bar'
    >> l = ( 'v', 'w' )
    je voudrais, en bouclant sur l, afficher les valeurs de v et w:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >> for x in l:
        print(x)
    v #je voudrais foo
    w #je voudrais bar
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    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 738
    Par défaut
    Salut,

    Citation Envoyé par N_BaH Voir le message
    je ne trouve pas d'informations sur la possibilité de faire des indirections, comme en shell
    Vous devez penser à ce que vous voulez réaliser avec Python et non essayer de traduire comment vous le feriez avec bash "shell" en Python.
    Et commencer par ne pas confondre variables et chaines de caractères:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> v = 'foo'; w = 'bar'
    >>> l = v, w
    >>> for x in l: print(x)
    ...
    foo
    bar
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 651
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut
    je vois que je me suis mal exprimer :

    j'ai une liste de chaînes, qui sont des noms de variables. Ces variables peuvent ne pas être assignées*, et je voudrais les tester.

    je pensais le faire ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    l = ( 'nomVar1', 'nomVar2' )
    for x in l:
        if not x: #quel mécanisme pour tester que les variables nomVar1 et nomVar2 existent et ont une valeur ?
            print(f"err: {x} absent.")
            exit(1)
    --
    * ne me demandez pas pourquoi, c'est pour le découvrir que je voudrais les tester.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    j'ai une liste de chaînes, qui sont des noms de variables.
    Pardon de faire le lourd mais il n'y a aucune raison que tu en arrives à cette situation. Et si tu y arrives c'est que quelque part tu as raté un truc plus en amont

    Citation Envoyé par N_BaH Voir le message
    * ne me demandez pas pourquoi, c'est pour le découvrir que je voudrais les tester.
    Ok pas de souci. Si c'est juste pour savoir comment le faire...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    >>> toto = "123"
    >>> var = "toto"
    >>> print(var)
    toto
    >>> print(eval(var))
    123
     
    >>> nomVar1 = "toto"
    >>> nomVar2 = "titi"
    >>> L = ("nomVar1", "nomVar2")
    >>> for x in L:
    ...     print(x, eval(x))
    ... 
    nomVar1 toto
    nomVar2 titi
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 651
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 651
    Par défaut
    Citation Envoyé par Sve@r
    Et si tu y arrives c'est que quelque part tu as raté un truc plus en amont
    mais, c'est pas moi, c'est l'autre.

    je fais des requêtes HTTP (requests.get(...)), et parfois, sans échouer pourtant, la réponse semble vide...

    ok pour eval()
    merci.

    edit: à départager avec globals(), alors
    parce que ce n'est pas destiné à demeurer, je vais privilégier le simple.

    merci.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    mais, c'est pas moi, c'est l'autre.
    Si ce n'est toi c'est donc ton frère... ou quelqu'un des tiens...

    Citation Envoyé par N_BaH Voir le message
    je fais des requêtes HTTP (requests.get(...)), et parfois, sans échouer pourtant, la réponse semble vide...
    Comme en SQL, Python possède une notion de "nullité" qui diffère de "vide/rempli"
    Code python : 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
    >>> def rien(): pass
    ... 
    >>> def vide(): return ""
    ... 
    >>> def rempli(): return "123"
    ... 
    >>> var = rien()
    >>> var is None
    True
    >>> bool(var)
    False
     
    >>> var = vide()
    >>> var is None
    False
    >>> bool(var)
    False
     
    >>> var = rempli()
    >>> var is None
    False
    >>> bool(var)
    True
    >>>

    Citation Envoyé par N_BaH Voir le message
    ok pour eval()
    Essaye tout de même de voir si tu peux l'éviter

    Citation Envoyé par N_BaH Voir le message
    edit: à départager avec globals(), alors
    C'est vrai que "globals()" j'ai pas eu le réflexe d'y penser ()
    C'est une fonction qui renvoie un dictionnaire de toutes les variables de ton code. Avec chaque variable utilisée comme clef
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    >> var = 123
    >>> globals()["var"]
    123
    >>> toto = "var"
    >>> globals()[globals()["toto"]]
    123
     
    >>> nomVar1 = "toto"
    >>> nomVar2 = "titi"
    >>> L = ("nomVar1", "nomVar2")
    >>> for x in L:
    ...     print(x, globals()[x])
    ... 
    nomVar1 toto
    nomVar2 titi
    Mais c'est une solution qui reste quand-même une "rustine"
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    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 738
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    j'ai une liste de chaînes, qui sont des noms de variables. Ces variables peuvent ne pas être assignées*, et je voudrais les tester.
    Une variable qui n'a pas été assignée n'existe pas et si on essaie d'y accéder une exception NameError sera levée.

    Maintenant, une variable (qui existe), c'est l'association d'une chaine de caractères avec un objet réalisée dans l'espace de noms globals()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> l = ( 'nomVar1', 'nomVar2' )
    >>> nomVar2 = ''
    >>> for x in l:
    ...     v = globals().get(x)
    ...     if v is None:
    ...        print(x, 'absent')
    ...     else:
    ...        print(x, v)
    ...
    nomVar1 absent
    nomVar2
    >>>
    Mais dans ce cas, on utilise globals() comme un simple dictionnaire qui associe chaine de caractère/clef à objet/valeur: autant utiliser un simple dictionnaire (pour ces choses là) car l'intérêt d'en faire des "variables" sera limité.

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

  8. #8
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 323
    Par défaut
    bonjour
    Citation Envoyé par N_BaH Voir le message
    j'ai une liste de chaînes, qui sont des noms de variables. Ces variables peuvent ne pas être assignées*, et je voudrais les tester.
    * ne me demandez pas pourquoi, c'est pour le découvrir que je voudrais les tester.
    les eval() et globals() c'est quand même ce qui se fait de plus moche en python !


    Tu devais "normalement" utiliser un dictionnaire : ton nom de variable devient (juste) une clé pour ce dictionnaire
    note: globals() retourne justement un dico

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     dico = {}
    dico["toto"] = 1
    dico["tata"] = 2
     
    for cle in dico:
        print("simili nom de variable bash", cle, "valeur:", dico[cle])
     
    if not "truc" in dico :
         print("clé/variable 'truc' existe pas")
    ----------
    je fais des requêtes HTTP (requests.get(...)), et parfois, sans échouer pourtant, la réponse semble vide...
    Désolé, mais ceci ne devrait avoir aucun rapport avec ta demande et ... une réponse vide ce n'est pas une variable inexistante.
    Tu as sans doute plus besoin de corriger ton code en amont que d'ajouter une mauvaise rustine sur un mauvais code.

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par N_BaH Voir le message
    je ne trouve pas d'informations sur la possibilité de faire des indirections, comme en shell
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ v=w
    $ w=foo
    $ echo ${!v}
    foo
    Parce que cette possibilité n'existe pas. Enfin si avec eval() mais si tu l'utilises pour ça c'est que tu as un défaut de conception. Python a plus de souplesse que le shell ce qui évite donc d'avoir recours aux indirections.

    Citation Envoyé par N_BaH Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >> v = 'foo'
    >> w = 'bar'
    >> l = ( 'v', 'w' )
    je voudrais, en bouclant sur l, afficher les valeurs de v et w:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >> for x in l:
        print(x)
    v #je voudrais foo
    w #je voudrais bar
    l=(v, w) et non l=('v', 'w')Après si tu veux aussi voir apparaitre le nom...
    [code]>> v = 'foo'
    >> w = 'bar'
    >> d = {"v" : v, "w" : w}
    >> for (x, y) in d.items():
    print("%s => %s" % (x, y))
    De là on peut se rendre compte alors que "v" et "w" perdent leur utilité...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 062
    Par défaut
    Hello,

    @N_Bah,

    Ce que tu veux s'appelle l'introspection en python, et pour cela on a le module inspect qui fait cela de manière propre, sans eval et sans globals.

    Voici un exemple que j'ai testé pour toi et ressemblant à ce que tu souhaites (vérifier que des noms de variables sous forme de chaînes de caractères soient présents dans un module python)

    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
    import inspect
    # obtenir le nom du module
    nom_module = inspect.getmodulename(__file__)
     
    # noms de variables à rechercher
    noms_variables = ['ma_variable_1', 'ma_variable_2', 'ma_variable_3']
     
    # définition de mes variables pour le test
    ma_variable_1 = 1
    #  ma_variable_2 = 2 pour vérifier son absence dans le module
    ma_variable_3 = 3
     
    if __name__ == '__main__':
        # obtenir une liste de tous les membres du module
        module = __import__(nom_module)
        membres = inspect.getmembers(module)
     
        # filtrer les membres qui correspondent aux noms de variables souhaités
        variables_presentes = [
            nom_variable for nom_variable, _ in membres
            if nom_variable in noms_variables
        ]
     
        print(variables_presentes)
    Je sais qu'en python on privilégie souvent le simple, mais attention, le simple peut être souvent trop simple pour être robuste et éviter certaines failles, comme la sécurité par exemple.
    Je conseille de manière assez soutenue de ne pas utiliser eval ou globals qui sont sources de bugs assez difficiles à debug.

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

Discussions similaires

  1. Premiers pas dans python
    Par thance dans le forum Général Python
    Réponses: 20
    Dernier message: 13/03/2007, 16h54
  2. integrer du code Assembleur (x86) dans python
    Par nephhh dans le forum Général Python
    Réponses: 2
    Dernier message: 11/02/2007, 11h50
  3. Masquer une commande système dans python
    Par Mysti¢ dans le forum Général Python
    Réponses: 5
    Dernier message: 03/11/2006, 16h33
  4. premiers pas dans Python - palindrome
    Par tarang dans le forum Général Python
    Réponses: 1
    Dernier message: 31/10/2006, 16h56
  5. Utilisation de Timer dans Python
    Par aliassaf dans le forum Général Python
    Réponses: 5
    Dernier message: 17/06/2006, 19h06

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