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 :

fonction changant une variable non definie comme global


Sujet :

Python

  1. #1
    Candidat au Club
    Inscrit en
    Février 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 8
    Points : 4
    Points
    4
    Par défaut fonction changant une variable non definie comme global
    Salut tout le monde.
    Pourquoi dans le premier code la fonction arrive à changer la variable définie dans le programme principal, alors que dans le second code il n'y arrive pas.
    Lorsque je cherche, je trouve qu'il ne peut être changer ni dans le premier ni dans le second : car les instructions d'une fonction peuvent lire la valeur d'une variable définie au niveau principal mais pas la modifié
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    def fonction():
        dic['a']='z'
    dic={}
    print dic
    fonction()
    print dic
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    def fonction():
        dic={'a':'z'}
    dic={}
    print dic
    fonction()
    print dic

  2. #2
    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 noureddine39,

    Dans le premier code tu rajoute une clé au dico
    Dans la seconde tu crée un dico local avec le même nom.

    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
    def fonc():
        dic['a']='z'
        print 'dic dans fonc', id(dic)
    dic={}
    print 'dic initial', id(dic)
    print dic
    fonc()
    print 'dic a la fin', id(dic)
    print dic
    def fonc1():
        dic1={'a':'z'}
        print 'dic1 dans fonc1', id(dic1)
    dic1={}
    print 'dic1 initial', id(dic1)
    print dic1
    fonc1()
    print 'dic1 a la fin', id(dic1)
    print dic1
    Ton dico est visible par ta fonction et avec dic['a']='z' tu appelle une méthode interne du dico. Il ne fais que son travail

    De même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    def fonc():
        a += 1
        print a
    a=1
    print a
    fonc()
    print a
    Ne fonctionne pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def fonc():
        b = a + 1
        print b
    a=1
    print a
    fonc()
    print a
    Oui, car a n'est qu'une variable : pas de méthode utilisée.

    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def fonc():
        li.append("new")
        print li
    li = []
    print li
    fonc()
    print li
    Fonctionne alors que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def fonc():
        li=["old"]
        print li
    li = []
    print li
    fonc()
    print li
    Non. Sur le même principe.

    @+

    Edit : Attention, je n'ai jamais dis que les variables n'avais pas de méthodes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a=1
    print type(a)
    print dir(a)
    Merci d'utiliser le forum pour les questions techniques.

  3. #3
    Candidat au Club
    Inscrit en
    Février 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 8
    Points : 4
    Points
    4
    Par défaut Pourquoi j'ai posé cette question !
    D'abord, je tiens à vous remercier PauseKawa, pour votre réponse bien claire
    et instructive.
    J'ai posé cette question, car j'ai lu dans le cours "apprendre à programmer avec python" (page 165), que vous devez connaitre certainement, une paragraphe qui est la suivante :

    Vous avez appris également que les instructions se trouvant à l'intérieur d'une fonction peuvent accéder aux variables au niveau principal, mais en lecture seulement :elles peuvent utiliser les valeurs de ces variables, mais pas les modifier (à moins de faire appel à l'instruction global)

  4. #4
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Points : 143
    Points
    143
    Par défaut
    Pour préciser les choses et compléter la réponse de PauseKawa.

    Il y a deux choses qui sont distinctes

    1) modifier une variable ou dit autrement attribuer un nouvel objet à la variable.
    C'est ce que tu fais avec l'instruction dic={'a':'z'}
    dic1 ne pointe plus vers le dictionnaire {} mais vers un nouveau dictionnaire {'a':'z'} (enfin, c'est ce qu'il devrait se passer si dic était déclarée comme variable globale).

    2) modifier l'objet vers lequel point la variable.
    C'est ce que tu fais avec l'instruction dic['a'] = 'z'.
    dic1 pointe toujours vers le même dictionnaire mais tu rajoutes le couple ('a', 'z') à ce dictionnaire.

    La phrase
    elles peuvent utiliser les valeurs de ces variables, mais pas les modifier (à moins de faire appel à l'instruction global)
    ne s'applique qu'au cas 1.

    Dans l'exemple que tu as donné, ce qu'il se passe, c'est qu'à partir du moment qu'il y a une affectation de variable dans une fonction (par exemple, dic = {'a' : 'z'}), cette variable dic est considérée comme locale et différente de la variable globale dic.

  5. #5
    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,

    Puisque tu est sur le passage de variables je te laisse regarder l'utilisation de self (et autres return) et je rajoute en information complémentaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class mesglobals():
        untruc=None
     
    def modif():
        mesglobals.untruc=1
        print mesglobals.untruc
     
    mesglobals.untruc='pouet'
    print mesglobals.untruc
    modif()
    print mesglobals.untruc
    Pour terminer pense qu'au niveau rapidité du code il est préférable d'utiliser une locale.

    Pour moi (avis perso) l'utilisation de global est la pour ouverte à toutes les fenêtres. Il est préférable de bien suivre ses variables et de s'en passer au maximum. C'est sans doute dur au début mais apprendre à s'en passer et sans aucun doute la meilleure école pour faire du code 'propre', du moins au niveau des variables.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  6. #6
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Points : 143
    Points
    143
    Par défaut
    Je suis d'accord, dans un programme bien codé, il ne devrait jamais y avoir besoin d'utiliser globals.

    Un (autre) petit exemple pour montrer les bizzareries des variables globales (même si au final, c'est assez logique).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def f():
       print a
    
    def g():
       print a
       a=1
    
    a=1
    f()
    >>> 1
    g()
    >>> UnboundLocalError: local variable 'a' referenced before assignment
    Dans la fonction f, a fait référence à la variable globale a
    Dans la fonction g, a fait référence à une variable locale différente de la variable globale a et du coup pas encore assigné.

  7. #7
    Candidat au Club
    Inscrit en
    Février 2010
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 8
    Points : 4
    Points
    4
    Par défaut Mieux vaut dire :
    Je pense qu'il vaut mieux dire :

    Une fonction peut tout faire d'une variable, sauf une nouvelle affectation.

    Car l' instruction - dic['a']='z' - est quant même une modification de la valeur contenue dans la variable dic
    Dite moi, ai-je raison ?

    Et merci pour vous tous, PauseKawa et Biribibi .

  8. #8
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Points : 143
    Points
    143
    Par défaut
    Oui. A partir du moment qu'il n'y a pas dans ta fonction de ligne du type

    maVariable = ...

    ou maVariable est une variable globale, il n'y aura pas de problème.

  9. #9
    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,

    C'est bizarre mais j'ai hésiter à poster sur cela ce matin. Attention aux noms de tes variables/objets et de bien les suivre.

    Citation Envoyé par noureddine39 Voir le message
    Je pense qu'il vaut mieux dire :
    Une fonction peut tout faire d'une variable, sauf une nouvelle affectation.
    Dite moi, ai-je raison ?
    Non. Le sujet est les valeurs :
    Vous avez appris également que les instructions se trouvant à l'intérieur d'une fonction peuvent accéder aux variables au niveau principal, mais en lecture seulement :elles peuvent utiliser les valeurs de ces variables, mais pas les modifier (à moins de faire appel à l'instruction global)
    Cela ne concerne pas les méthodes mais les valeurs.

    --------------------------------------------------------------------------------------------------- Notes :

    l'intérieur/principal : Cela fais référence à la 'visibilité' (Pardon pour la visibilité mais cela parle => Voir self et la closure entre autre.) Ne pas confondre un 'niveau' (dixit le texte, remarquez que je ne contredit pas l'auteur) et global.

    Une fonction : Une fonction retourne quelque chose, une procédure non.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def fonction(a):
        a+=1
        return a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def procedure():
        print a
    Bon, je pense que le sujet est résolu.

    @+
    Merci d'utiliser le forum pour les questions techniques.

  10. #10
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Points : 143
    Points
    143
    Par défaut
    Pour la distinction entre procédure et fonction, je crois qu'elle n'a pas trop lieu dans la communauté Python, les deux sont considérés comme des fonctions.

    De toute façon, une fonction renvoie toujours quelque chose, si il n'y a pas de return, la valeur None est renvoyée par défaut.
    Mais bon, c'est toujours bien de connaître le vocabulaire.

    Sinon, dans la phrase:
    Vous avez appris également que les instructions se trouvant à l'intérieur d'une fonction peuvent accéder aux variables au niveau principal, mais en lecture seulement :elles peuvent utiliser les valeurs de ces variables, mais pas les modifier (à moins de faire appel à l'instruction global)
    même si c'est tiré d'un bouquin, je trouve que ça peut prêter à confusion.
    Je dirais plutôt mais ne peut pas réassigner la variable. Mais bon, c'est juste mon point de vue.

  11. #11
    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,

    Citation Envoyé par Biribibi Voir le message
    Pour la distinction entre procédure et fonction, je crois qu'elle n'a pas trop lieu dans la communauté Python, les deux sont considérés comme des fonctions.

    De toute façon, une fonction renvoie toujours quelque chose, si il n'y a pas de return, la valeur None est renvoyée par défaut.
    Mais bon, c'est toujours bien de connaître le vocabulaire.
    Tu fais bien de le préciser Biribibi : C'est une (grosse) erreur de ma part de dire qu'une procédure ne retourne rien (dixit bibi ). Il est impératif de se souvenir que cela retourne None car un b=a.uneprocedure() et patatras b=None...

    @+

    Ps : C'est loin du sujet ça non ? Désolé noureddine39, j'arrête de faire mon
    Merci d'utiliser le forum pour les questions techniques.

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/04/2015, 14h09
  2. Réponses: 4
    Dernier message: 22/01/2013, 11h01
  3. Réponses: 6
    Dernier message: 03/02/2010, 14h00
  4. Réponses: 1
    Dernier message: 14/11/2009, 07h07
  5. copie d'une variable non reconnue dans une fonction
    Par paragoge dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 27/10/2009, 13h30

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