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 :

problème de portée de variable


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Responsable Dev
    Inscrit en
    Décembre 2003
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Responsable Dev

    Informations forums :
    Inscription : Décembre 2003
    Messages : 788
    Par défaut problème de portée de variable
    bon le titre indique clairement mon problème
    je suis sous python 3.1 et j'ai un soucis de porté de variable et de valeur par défaut de variable
    j'ai simplifié mon code à l'extrême (le code en lui même est donc stupide ... mais identifie bien mon soucis
    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
     
    def list_path(p, l=[]):
            """return a list
            p list
            l list
            """
            for i in p:
                l.append(i)
            return l
     
     
    print('premier lancement')
    print(list_path([1,2,3]))
    print()
    print('deuxieme lancement')
    print(list_path([4,5,6]))
    je m'attendais à obtenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    premier lancement
    [ 1,2,3]
    deuxieme lancement
    [ 4,5,6]
    et j'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    premier lancement
    [ 1,2,3]
    deuxieme lancement
    [ 1,2,3,4,5,6]
    cela devient plus drôle si j'écris cela comme ça
    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
     
    def list_path(p, l=""):
            """return a list
            p list
            l list
            """
            for i in p:
                l = l + str(i)
            return l
     
     
    print('premier lancement')
    print(list_path([1,2,3]))
    print()
    print('deuxieme lancement')
    print(list_path([4,5,6]))
    et là j'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    premier lancement
    [ 1,2,3]
    deuxieme lancement
    [ 4,5,6]
    la portabilité des variables dépends de la nature de la variable ?
    je code en python depuis des années et c'est la première fois que je constate cela ...

  2. #2
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def liste(p):
        l=[]
        for i in p:
            l.append(i)
        print l
    différent de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def liste(p, l=[]):
        for i in p:
            l.append(i)
        print l
    Dans le 1er code on initialise notre liste vide à chaque appel de fonction, la liste l n'est donc pas visible, c'est une variable locale

    Cependant le 2eme code est ton cas, au départ tu ne spécifies pas de liste l, donc elle est vide. Mais après le résultat retourné, ta liste l existe, et il l'a reprend comme argument parce-qu'il considère la liste l comme une variable globale.

    En gros mon 2eme code pourrait ressembler à cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> def test(a):
    	for i in a:
    		l.append(i)
    	return l
     
    >>> l=[]
    >>> test([3, 4, 5])
    [3, 4, 5]
    >>> test([7, 8, 9])
    [3, 4, 5, 7, 8, 9]
    >>>
    Je ne sais pas si j'ai été assez clair, mais c'est pas toujours évident d'expliquer simplement

  3. #3
    Membre émérite
    Profil pro
    Responsable Dev
    Inscrit en
    Décembre 2003
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Responsable Dev

    Informations forums :
    Inscription : Décembre 2003
    Messages : 788
    Par défaut
    Bonjour et tout d'abord merci pour ta réponse
    j'ai bien compris la notion de portabilité mais là j'ai plutôt un soucis d'initialisation d'une variable
    le faite de marquer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    def liste(p, l=[]):
    cela signifie que pour appeler la fonctionner il faut au moins un paramètre (p), le paramètre est optionnel et par défaut est égale à []

    Ce qui m'embête le plus dans mon problème est que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    def liste(p, l=[]):
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    def liste(p, l=""):
    non pas le même comportement

    si quelqu'un peut m'expliquer pourquoi le comportement n'est pas le même je suis preneur

  4. #4
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    En fait, j'ai l'impression que python décide de manière assez confuse (pour moi en tout cas) quand les paramètres sont passés par valeur et quand ils sont passés par référence.

    Les types simples (int, float, string) sont passés par valeur, donc il sont instanciés tout beaux tout neuf au moment de l'appel, alors que les types plus "compliqués" (list, dict, objets utilisateurs,... ) sont passés par référence.

    Je subodore une conséquence directe de l'implémentation en C...
    en tous cas, je trouve ça très moche...

    Peut être y a-t-il une doc que je n'ai pas lue et qui explique tout ça ?

    (hum... je ne suis pas sûr d'avoir fait avancer le schmilblick...)

  5. #5
    Membre émérite
    Profil pro
    Responsable Dev
    Inscrit en
    Décembre 2003
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Responsable Dev

    Informations forums :
    Inscription : Décembre 2003
    Messages : 788
    Par défaut
    détrompe toi: tu offres une explication et surtout comme moi tu n'as pas trouvé de doc expliquant tout cela ... je cherche encore l'explication

    sinon pour éviter ce soucis on peut écrire
    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 list_path(p, l=None):
            """return a list
            p list
            l list
            """
            if l == None:
                l = []
            for i in p:
                l.append(i)
            return l
     
     
    print('premier lancement')
    print(list_path([1,2,3]))
    print()
    print('deuxieme lancement')
    print(list_path([4,5,6]))
    et on obtient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    premier lancement
    [ 1,2,3]
    deuxieme lancement
    [ 4,5,6]

  6. #6
    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
    L'initialisation des paramètres nommés avec un type 'mutable' est un piège dans lequel tombent régulièrement les programmeurs Python.
    La dernière discussion sur le sujet a quelques semaines, voir: post5351180
    qui en aborde les différents aspects.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre émérite
    Profil pro
    Responsable Dev
    Inscrit en
    Décembre 2003
    Messages
    788
    Détails du profil
    Informations personnelles :
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Responsable Dev

    Informations forums :
    Inscription : Décembre 2003
    Messages : 788
    Par défaut
    merci j'avais louper l'explication

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

Discussions similaires

  1. Problème de portée de variables (VBS)
    Par befast dans le forum Windows
    Réponses: 0
    Dernier message: 18/09/2007, 09h40
  2. [Mail] problème de portée de variables
    Par xclam dans le forum Langage
    Réponses: 2
    Dernier message: 12/04/2007, 09h35
  3. Problème de Portée de Variable
    Par Julien_C++ dans le forum C++
    Réponses: 7
    Dernier message: 18/09/2006, 10h13
  4. [VBA-E] Problème de portée de variable [débutant]
    Par vivelesgnous dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 01/03/2006, 18h28
  5. [XSL]Problème de portée des variables
    Par djulesp dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 17/09/2004, 10h34

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