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 :

global - pas toujours


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Formateur en informatique
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : Suisse

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Par défaut global - pas toujours
    Avec Python 2.72, j'ai voulu utiliser deux variables globales en float entre modules. A ma surprise, ça ne fonctionne pas, alors que pour une liste et un dictionnaire, c'est OK. Curieusement, l'initilisation (ici a_var = 1) est vue correctement des deux modules.
    Exemple, le fichier a.py:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    a_var = 1   # globale, vraiment?
    l = [1]     # global
     
    def mod_var():
        global a_var, l
        print "vu de a, avant: %d, %d" %(a_var, l[0])
        a_var = 10
        l[0] = 10
        print "vu de a, apres: %d, %d" %(a_var, l[0])
    Et le fichier b.py:
    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
     
    import sys
    from a import *
     
    def mod_var2():
        global a_var, l
        a_var = 20
        l[0] = 20
     
    def main(p):
        global a_var, l
        print "vu de b, avant mod_var a: %d, %d" %(a_var, l[0])
        mod_var()
        print "vu de b, apres mod_var: %d, %d" %(a_var, l[0])
        mod_var2()
        print "vu de b, apres mod_var2: %d, %d" %(a_var, l[0])
        print "fin"
     
    # Starts here
    if __name__ == '__main__':
        main(sys.argv )
    #end main
    Le résultat est le suivant:
    vu de b, avant mod_var a: 1, 1
    vu de a, avant: 1, 1
    vu de a, apres: 10, 10
    vu de b, apres mod_var: 1, 10
    vu de b, apres mod_var2: 20, 20
    fin
    On voit donc clairement que la variable a_var est une copie dans le module b.py, bien que l'initialisation de a.py s'effectue, ce qui est trompeur!

  2. #2
    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 ça s’explique ainsi*:
    *les listes sont des objets «*complexes*», mutables, et sont donc copiées par références (autrement dit, une copie d’une liste utilise le même objet que la liste initiale, et donc modifier l’une affecte l’autre).
    *Les floats sont des objets «*simples*», et qui sont copiés par valeur (donc, modifier la copie n’affecte pas l’originale).


    *Lorsque tu écris from a import *, tu évalues a, si c’est la première fois qu’il est importé (et donc initialise tes variables globales), puis tu copies l’ensemble du dict global de a dans celui de b. Donc, b.a_var n’est plus le même objet que a.a_var, et modifier l’un n’affecte plus l’autre. Pour que cela marche, il faudrait, dans b, que tu utilises a.a_avr.

    Démonstration*:

    a.py*:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    a_var = 1   # globale, vraiment?
    l = [1]     # global
     
    def mod_var():
        global a_var, l
        print "vu de a, avant: %d (objet %i), %d (objet %i)" %(a_var, id(a_var), l[0], id(l))
        a_var = 10
        l[0] = 10
        print "vu de a, apres: %d (objet %i), %d (objet %i)" %(a_var, id(a_var), l[0], id(l))
    b.py*:
    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
    import sys
    import a
    from a import *
     
    def mod_var2():
        global a_var, l
        a_var = 20
        l[0] = 20
     
    def mod_var3():
        a.a_var = 30
        a.l[0] = 30
     
    def main(p):
        global a_var, l
        print "vu de b, avant mod_var a: %d (objet %i), %d (objet %i)" %(a_var, id(a_var), l[0], id(l))
        mod_var()
        print "vu de b, apres mod_var: %d (objet %i), %d (objet %i)" %(a_var, id(a_var), l[0], id(l))
        mod_var2()
        print "vu de b, apres mod_var2: %d (objet %i), %d (objet %i)" %(a_var, id(a_var), l[0], id(l))
        print("----- Now using a.a_var -----")
        mod_var3()
        print "vu de b, apres mod_var3: %d (objet %i), %d (objet %i)" %(a.a_var, id(a.a_var), a.l[0], id(a.l))
        mod_var()
        print "vu de b, apres mod_var: %d (objet %i), %d (objet %i)" %(a.a_var, id(a.a_var), a.l[0], id(a.l))
        print "fin"
     
    # Starts here
    if __name__ == '__main__':
        main(sys.argv )
    #end main
    Résultat*:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    vu de b, avant mod_var a: 1 (objet 16758712), 1 (objet 17527296)
    vu de a, avant: 1 (objet 16758712), 1 (objet 17527296)
    vu de a, apres: 10 (objet 16758496), 10 (objet 17527296)
    vu de b, apres mod_var: 1 (objet 16758712), 10 (objet 17527296)
    vu de b, apres mod_var2: 20 (objet 16758256), 20 (objet 17527296)
    ----- Now using a.a_var -----
    vu de b, apres mod_var3: 30 (objet 16758016), 30 (objet 17527296)
    vu de a, avant: 30 (objet 16758016), 30 (objet 17527296)
    vu de a, apres: 10 (objet 16758496), 10 (objet 17527296)
    vu de b, apres mod_var: 10 (objet 16758496), 10 (objet 17527296)
    fin
    Encore une bonne raison d’éviter d’utiliser la syntaxe from foo import *, amha…

  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
    Citation Envoyé par ymasur Voir le message
    Exemple, le fichier a.py:
    Je vois :
    1 = [1]
    affectation à un entier? bien sur que non.
    PEP 8:
    Prescriptive: Naming Conventions

    Names to Avoid

    Never use the characters `l' (lowercase letter el), `O' (uppercase
    letter oh), or `I' (uppercase letter eye) as single character variable
    names.

    In some fonts, these characters are indistinguishable from the numerals
    one and zero. When tempted to use `l', use `L' instead.
    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

Discussions similaires

  1. Fonction ne retournant pas toujours une valeur
    Par mastochard dans le forum C
    Réponses: 14
    Dernier message: 25/05/2006, 12h13
  2. [CSS] a:active ne fonctionne pas toujours ?
    Par KpTn dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 10/05/2006, 17h25
  3. Réponses: 9
    Dernier message: 04/10/2005, 19h39
  4. db enregistre pas toujour
    Par cre3000 dans le forum Bases de données
    Réponses: 1
    Dernier message: 23/05/2005, 12h16
  5. [VB6] [Validate et CausesValidation] Ca marche pas toujours !!!
    Par HPJ dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 16/12/2003, 22h09

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