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 :

Equivalent du perl @$var en python


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 12
    Par défaut Equivalent du perl @$var en python
    Bonjour,

    je cherche un moyen élégant d'écrire un bout de fonction qui est en perl :

    où $var contiendrait par ex 'tableau'
    ce qui fait qu'au final j'accède à @tableau

    En python, j'ai ma variable var='tuple' et j'ai déclaré plus tôt tuple = ('a','b','c')
    et je veux avoir quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for i in ????:
              ....
    où j'utilise ma variable var dans les ?????


    Merci d'avance.

  2. #2
    Membre Expert 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
    Par défaut
    Bonjour,

    Pour toute autre chose qu'un tuple j'aurais dit getattr...
    Pour les tuples utiliser les dicos ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> exemple = ('a','b','c')
    >>> var='exemple'
    >>> for i in locals()[var]:
    ...     print i
    ... 
    a
    b
    c
    Dans l'attente d'une réponse plus pro

    @+

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Août 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 12
    Par défaut
    Merci beaucoup. En effet, ça fonctionne très bien chez moi (et ça raccourcit mon code de 60 lignes).

    Je ne suis pas encore arrivé à cette partie de mon cours, il faut que je buche ça

  4. #4
    Membre Expert 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
    Par défaut
    Hola... Ce n'est qu'une idée...

    Attention à la portée

    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
    >>> def getvar(varname):
    ...     if varname in locals():
    ...         return locals()[varname]
    ...     elif varname in globals():
    ...         return globals()[varname]
    ... 
    >>> exemple = ('a','b','c')
    >>> var='exemple'
    >>> for i in getvar(var):
    ...     print i
    ... 
    a
    b
    c
    >>> def test():
    ...     exemple1 = ('a','b','c')
    ...     var1='exemple1'
    ...     for i in getvar(var1):
    ...          print i
    ... 
    >>> test()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 5, in test
    TypeError: 'NoneType' object is not iterable
    >>>
    Bon code

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Pausekawa, c’est bien essayé mais il y a un petit twist dans ton dernier code du message #4

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def getvar(varname):
        if varname in globals():
            return globals()[varname]
    donne exactement les mêmes résultat que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def getvar(varname):
        if varname in locals():
            return locals()[varname]
        if varname in globals():
            return globals()[varname]




    Ce qui est visé:

    La valeur de la référence varname est censément un objet de type chaîne ayant un rôle d’identifiant quelque part dans le programme:
    chaîne 'exemple' dans le premier cas, chaîne 'exemple1' dans le second cas.

    À partir d’une valeur chaîne de varname, il faut trouver l’objet que cette chaîne identifie.

    À cette fin, il faut interroger l’espace de noms contenant varname, c’est à dire le dictionnaire dans lequel se trouve cette valeur chaîne de varname en tant que clé, car un espace de noms est un dictionnaire qui établit la correspondance entre l’identifiant d’un objet et l’objet lui-même situé en mémoire.





    Explication du twist:

    En écrivant if varname in locals() au sein de la fonction getvar() , tu cherches varname dans l’espace de noms de la fonction getvar() , c’est à dire la valeur chaîne de varname parmi les clés du dictionnaire locals() de la fonction getvar()

    Or, de par le rôle de getvar() , l’objet dont l’identifiant est la valeur de varname ne peut d’évidence pas être congénital à la fonction getvar() : sa définition se situe au contraire dans un niveau fonctionnel quelconque extérieur à getvar().

    La valeur de varname qui identifie l’objet voulu n’est donc jamais dans l’espace de noms de getvar()
    ==> varname in locals() sera donc toujours False

    Par contre bien sûr:
    def getvar(varname)
    => la valeur chaîne varname est dans les values de l’espace de noms locals() de getvar() , référencée par l’identifiant ’varname’ . Ce qui est sans doute la source de l’imbroglio.

    Si ton code donne l’apparence de fonctionner une fois et pas la fois suivante, c’est de par le seul résultat de
    if varname in globals():
    Ce que montre ton code, c'est que globals() comme seul niveau fonctionnel exploré, c’est insuffisant dès que l’objet voulu n’est pas défini au niveau d’un module.




    Le code suivant illustre tout ceci:

    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
    def getvar(varname):
        print 'globals() '+\
          '\n          '.join( repr(x) for x in globals().items()
                               if x[0] not in ('__builtins__','__package__','__name__','__doc__'))
        print'\n---- DANS FONCTION GETVAR(varname) --------------------'
        print 'parametre varname a pour valeur: ',repr(varname),'   de ',type(varname)
        print 'locals() vu dans getvar est    : ',locals()
        print '   varname in locals()           :::  varname in globals()'
        print '       ',varname in locals(),'\t\t\t :::\t  ',varname in  globals()
        print '   varname in locals().values()  :::  varname in globals().values()'
        print '       ',varname in locals().values(),'\t\t\t :::\t  ',varname in globals().values()
        print '--------------------------------------------------------\n'
     
        if varname in locals():
            print 'je passe dans if varname in locals()'
            return locals()[varname]
        elif varname in globals():
            print 'je passe dans if varname in globals()'
            return globals()[varname]
        else:
            print 'je ne passe dans rien du tout'
            return ('- rien du tout','- a iterer')
     
    exemple = ('a','b','c')
    var='exemple'
    for i in getvar(var):
        print i
     
     
    def test():
        exemple1 = ('a','b','c')
        var1='exemple1'
        print '\n\nlocals() de test()',locals()
        for i in getvar(var1):
             print i
     
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    globals() ('exemple', ('a', 'b', 'c'))
              ('getvar', <function getvar at 0x010BB270>)
              ('var', 'exemple')
     
    ---- DANS FONCTION GETVAR(varname) --------------------
    parametre varname a pour valeur:  'exemple'    de  <type 'str'>
    locals() vu dans getvar est    :  {'varname': 'exemple'}
       varname in locals()           :::  varname in globals()
            False 			 :::	   True
       varname in locals().values()  :::  varname in globals().values()
            True 			 :::	   True
    --------------------------------------------------------
     
    je passe dans if varname in globals()
    a
    b
    c
     
     
    locals() de test {'exemple1': ('a', 'b', 'c'), 'var1': 'exemple1'}
    globals() ('exemple', ('a', 'b', 'c'))
              ('i', 'c')
              ('test', <function test at 0x010BB2B0>)
              ('getvar', <function getvar at 0x010BB270>)
              ('var', 'exemple')
     
    ---- DANS FONCTION GETVAR(varname) --------------------
    parametre varname a pour valeur:  'exemple1'    de  <type 'str'>
    locals() vu dans getvar est    :  {'varname': 'exemple1'}
       varname in locals()           :::  varname in globals()
            False 			 :::	   False
       varname in locals().values()  :::  varname in globals().values()
            True 			 :::	   False
    --------------------------------------------------------
     
    je ne passe dans rien du tout
    - rien du tout
    - a iterer



    C’est donc bien une question de portée, toutefois pas à examiner comme tu l’as traitée, la plus enfouie (locals() de getvar() dans lequel la valeur de varname n’est jamais ) avant le niveau global.
    De plus, en n'examinant que locals() enfoui et globals() , on saute tous les niveaux fonctionnels intermédiaires entre getvar() et le niveau global de module.





    Ce qu’il faudrait faire, c’est examiner tous les niveaux fonctionnels situés entre (et y compris) le niveau module ( globals() ) et la fonction englobante de getvar() ( locals() dans lequel il y a ('getvar', <function getvar at 0x010BB270>) )



    Et bien, après avoir moult écumé les docs pour trouver une piste, il m’apparaît que ce ne doit être possible:

    - ni d’obtenir l’espace de nom d’une fonction ( soit en descendant à partir de l’espace de noms global, soit en descendant à partir d’un espace de nom de fonction inférieur au niveau global ) sans que l’interpréteur se situe dans cette fonction

    - ni de remonter d’une fonction enchassée dans une autre pour obtenir l’espace de noms local de cette fonction de niveau supérieur



    Pour ce qui est d’essayer de descendre en cascade du niveau module vers les fonctions à partir de l’espace de noms global, on peut bien partir de l’espace de nom global, puisque l’interpréteur peut le consulter en appelant globals() , même d’un point interne à une fonction; mais je ne sais pas comment descendre à partir de globals().


    Et pour ce qui est d’essayer de remonter d’une fonction getvar() à la fonction qui l’englobe, j’ai eu beau examiner les infos contenues dans les attributs co_freevars, co_varnames, co_cellvars, etc de l’attribut func_code , ou dans func_closure[0].cell_contents, je ne suis tombé sur aucun moyen de sortir vers l’espace de noms extérieur à une fonction pour obtenir l’espace de noms qui englobe cette fonction.


    Si quelqu’un a des lumières sur ce problème, je serai très intéressé de les lire.



    ---------------------------------------------

    La seule mesure qui puisse être prise à mon sens est d’appeler une fonction getvar() , en un point du programme où on pense avoir besoin de l’objet identifié par la valeur de varname, en lui fournissant le dictionnaire locals() existant en ce point;
    en espérant que l’objet référencé par varname sera soit dans locals() existant à ce point soit dans globals()


    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
    def getvar(varname,dee = locals()):
        if varname in dee:
            print "j'ai trouve l'identifiant "+repr(varname)+" dans locals()"
        elif varname in globals():
            print "j'ai trouve l'identifiant "+repr(varname)+" dans globals()"
        else:
            print "je n'ai pas trouve l'identifiant  " + repr(varname)
        print
     
    exemple = ('a','b','c')
    var='exemple'
    getvar(var,dee = locals()) 
     
    def test():
        exemple1 = ('d','e','f','g')
        var1='exemple1'
        getvar(var1,dee = locals())
     
        exemple2 = ('P','Q','R')
        var2='exemple2'
        def inner():
            getvar(var2,dee = locals())
     
            getvar(var,dee = locals())      
     
        inner()
     
    test()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    j'ai trouve l'identifiant 'exemple' dans locals()
     
    j'ai trouve l'identifiant 'exemple1' dans locals()
     
    je n'ai pas trouve l'identifiant  'exemple2'
     
    j'ai trouve l'identifiant 'exemple' dans globals()

  6. #6
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    bonjour,
    Citation Envoyé par eyquem
    Et bien, après avoir moult écumé les docs pour trouver une piste, il m’apparaît que ce ne doit être possible:

    - ni d’obtenir l’espace de nom d’une fonction ( soit en descendant à partir de l’espace de noms global, soit en descendant à partir d’un espace de nom de fonction inférieur au niveau global ) sans que l’interpréteur se situe dans cette fonction

    - ni de remonter d’une fonction enchassée dans une autre pour obtenir l’espace de noms local de cette fonction de niveau supérieur
    si, on peut tout à fait remonter la pile des appels:

    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 sys
    a = 3
    def getvar(varname):
        f = sys._getframe(1)
        locals = f.f_locals
        globals = f._f_globals
        if varname in locals:
            return locals[varname]
        if varname in globals:
            return gloabls[varname]
    def toto():
        b = 8
        print getvar('a') # accède à la portée globale de toto
        print getvar('b') # accède à la portée locale de toto
    toto()
    produit comme résultat:

    c'est faisable, mais je trouve ça moche...

    il n'y a qu'une seule fois où j'ai vraiment eu besoin d'aller chercher ce type de mécanisme (pour un class advisor) et cela est implémenté dans pyProtocols (http://peak.telecommunity.com/PyProtocols.html)

Discussions similaires

  1. Equivalent des structures Matlab en Python
    Par tazgero dans le forum Calcul scientifique
    Réponses: 16
    Dernier message: 31/12/2010, 18h40
  2. Equivalent sort -u unix en python
    Par AnsuzPeorth dans le forum Général Python
    Réponses: 7
    Dernier message: 13/03/2010, 18h37
  3. Equivalence de Perl en Awk
    Par blacksnake dans le forum Langage
    Réponses: 1
    Dernier message: 12/01/2008, 21h04
  4. Equivalence de Perl en Awk
    Par blacksnake dans le forum Shell et commandes GNU
    Réponses: 0
    Dernier message: 03/01/2008, 16h30
  5. [Debutant perl] Equivalent sous perl
    Par griese dans le forum Langage
    Réponses: 12
    Dernier message: 19/12/2006, 09h36

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