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 :

pointeurs des variables en python


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 13
    Par défaut pointeurs des variables en python
    Bonjour,

    Je me pose une question juste par curiosité. Pourquoi si on écrit :
    a=1
    b=a
    a=0

    alors b=0, alors que ce n'est pas le cas dans d'autre langages comme VB par exemple.
    En + clair, pourquoi en python quand une variable est définie comme égale à une autre, elle continue de pointer vers le même objet ?
    Quelles sont les facteurs qui mènent vers ce choix dans le design d'un langage ?
    Merci s'il y en a qui ont le temps de répondre

  2. #2
    Membre expérimenté Avatar de zancrows
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    159
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2016
    Messages : 159
    Par défaut
    Bonjour dans votre exemple v devrait garder la valeur 1 et non pas être égale à 0.

    dans une console python (python 3.7.1) quand je fais votre exemple j'ai ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    >>> a = 1
    >>> b = a
    >>> a = 0
    >>> b    
    1        
    >>> a    
    0        
    >>>

  3. #3
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    2 cas de figures :
    1 ) Si a est non mutable (un entier, un tuple, une chaine de caractère, ...), alors b est une nouvelle variable qui contient une copie de ce qu'il y avait dans a.
    2 ) Si a est mutable (une liste, un objet, ... ), alors b est un alias de plus pour accéder à l'information contenu dans a. En d'autre termes a et b pointe sur la meme données mémoire. Ceci veut dire que vos variables sont liées : modifier l'une impacte l'autre !

    On peut s'en rendre conte ainsi en printant les adresses mémoires :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    a = 0
    b = a
     
    print(id(a))
    print(id(b)) ### id different ici, un entier est non mutable
     
    a = [0]
    b = a
     
    print(id(a))
    print(id(b)) ### id identique ici, une liste est mutable
    NB : Notez qu'en Python, par défaut, tout est objet !
    NB 2 : Vous pouvez forcer des copies de mutables grace au module copy

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 799
    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 799
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par amapic Voir le message
    Bonjour,
    Bonjour

    Citation Envoyé par amapic Voir le message
    Je me pose une question juste par curiosité. Pourquoi si on écrit :
    a=1
    b=a
    a=0

    alors b=0, alors que ce n'est pas le cas dans d'autre langages comme VB par exemple.
    Ce n'est pas non plus le cas en Python. b reste à 1. Merci d'être passé.

    Citation Envoyé par lg_53 Voir le message
    On peut s'en rendre compte ainsi en printant les adresses mémoires :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a = 0
    b = a
     
    print(id(a))
    print(id(b)) ### id different ici, un entier est non mutable
    Ben non. Il se trouve que si b=a, alors id(b)=id(a) que ce soit pour des mutables ou des immuables.

    Je me demande même si id() signifie bien "adresse de". Parce que déjà, quand on tape id(1) on obtient bien un retour or je vois mal la valeur "1" avoir une adresse mémoire (en tout cas, en C, printf("%p", &1) ne compile pas).
    Et quand on développe avec ceci
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    a=1
    print(id(a))				# Ca donne 10771520 tout le temps, et peut-être même sur toutes les machines (d'ailleurs id(1) donne aussi 10771520 )
     
    a=0
    print(id(a))				# Ca donne 10771488 tout le temps
     
    a=1
    print(id(a))				# Ca redonne 10771520

    Je penserais plutôt que id() signifie "identifiant de", le terme "identifiant" étant plus à prendre comme un checksum qu'une adresse. Et ça expliquerait alors pourquoi id(a) = id(b) quand a = b...

    @amapic: ce n'est pas parce qu'il s'est trompé dans son exemple que son explication est fausse. Si tu copies un objet complexe de façon basique, tu te retrouves avec deux pointeurs pointant vers le même objet. La modif de l'un se répercutera dans l'autre
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    a=[1, 2, 3, 4, 5]
    b=a
    print(a)				# Ca donne [1, 2, 3, 4, 5]
    print(b)				# Ca donne [1, 2, 3, 4, 5]
     
    a[0]=100
    print(a)				# Ca donne [100, 2, 3, 4, 5]
    print(b)				# Ca donne [100, 2, 3, 4, 5]
    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
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 676
    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 676
    Par défaut
    Salut,

    Citation Envoyé par Sve@r Voir le message
    Je me demande même si id() signifie bien "adresse de". Parce que déjà, quand on tape id(1) on obtient bien un retour or je vois mal la valeur "1" avoir une adresse mémoire (en tout cas, en C, printf("%x", &1) ne compile pas).
    En CPython, c'est une adresse à partir de laquelle on peut récupérer l'objet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> import ctypes
    >>> a = "hello world"
    >>> print (ctypes.cast(id(a), ctypes.py_object).value)
    hello world
    >>>
    ... mais il est préférable de ne pas l'utiliser ainsi.

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

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    L'exemple aurait été plus parlant sur des floatants. Quelques éléments de réponses sur la fonction id :

    http://sametmax.com/id-none-et-bidou...ire-en-python/

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 799
    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 799
    Billets dans le blog
    1
    Par défaut
    Oui, je l'avais déjà lu. Eux ils justifient le fait que id(1) fonctionne parce que toutes les constantes d'un code se retrouvent stockées dans une sorte de "monde magique" contenant toutes les constantes apparaissant dans le code. Mais cela explique-t-il le fait que sous P3 (mais pas sous P2), id(1) renvoie toujours 10771520 (Python v3.4.2) même si je le demande dans différentes instances Python ? En tout cas je n'arrive pas à avoir autre chose (enin si, j'ai eu 10943008 sur une autre machine utilisant Python 3.6.5 ce qui infirme l'idée de checksum mais là, j'ai toujours 10943008).
    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]

  8. #8
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Mais cela explique-t-il le fait que sous P3 (mais pas sous P2), id(1) renvoie toujours 10771520 (Python v3.4.2) même si je le demande dans différentes instances Python ?
    Sur le compilateur online
    https://repl.it/languages/python3
    si tu lances le code :

    tu obtiendras des résultats différents à chaque run. Mais si en console tu tapes plusieurs fois la commande id(1), tu obtiens un id identique, commun à toute la session. Et si tu réinitialise (rafraichi la page), tu un nouvel id, qui est conservé tout au long de cette session (si tu répètes id(1), tu retrouves, le meme résultat que celui fournit à la 1ere exécution de la session).

    J'en conclu donc qu'il y a une sorte d'optimisation sur le stockage des constantes pour une session donnée. Cette optimisation peut procéder de manière différente selon les compilateur je pense. Sur certaines machine, il est également possible que cet espace mémoire soit également confondu pour toutes les sessions (as tu essayé en lancant plusieurs sessions simultannées?). D'autre part ces constantes ont peut etre des emplacements mémoire privilégié prédéfini, ce qui pourrait expliquer que tu constates des id identiques meme en changeant de machine.

    Ces arguments n'engage que moi, car j'avoue ne jamais m'être penché autant que cela sur la question.

    Un dernier petit test venant étayé la théorie de l'optimisation faite par le compilateur:
    Code 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x=1e23
     
    a=int(x)
    print(id(a))
     
    b=int(x)
    print(id(b))
    Code 2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x=int(1e23)
     
    a=x
    print(id(a))
     
    b=x
    print(id(b))
    Dans le code 2, les id sont les mêmes, alors que pas dans le code 1 !

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

    Citation Envoyé par lg_53 Voir le message
    J'en conclu donc qu'il y a une sorte d'optimisation sur le stockage des constantes pour une session donnée. Cette optimisation peut procéder de manière différente selon les compilateur je pense.
    Les constantes sont les entiers entre -5 et 256 comme mentionné dans la documentation de PyObject* PyLong_FromLong
    PyObject* PyLong_FromLong(long v)
    Return value: New reference.

    Return a new PyLongObject object from v, or NULL on failure.

    The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)
    et bien sûr çà ne s'applique qu'a l'implémentation CPython de Python.

    Après côté id, c'est supposé retourner un identifiant unique pendant toute la durée de vie de l'objet.... mais pas d'une instance de l'interpréteur à l'autre (et à condition qu'on n'ait pas surchargé cet id) et il est ré-utilisable après la destruction de l'objet.

    Sur CPython, c'est l'adresse de l'objet: voir la documentation.

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

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 799
    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 799
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lg_53 Voir le message
    Mais si en console tu tapes plusieurs fois la commande id(1), tu obtiens un id identique, commun à toute la session.
    C'est aussi le cas si tu mets ça dans un script et que tu exécutes le script...

    Citation Envoyé par lg_53 Voir le message
    as tu essayé en lancant plusieurs sessions simultannées?).
    Oui. Mais comme je suis sur Unix, chaque session est indépendante de chaque autre.

    Citation Envoyé par lg_53 Voir le message
    Un dernier petit test venant étayé la théorie de l'optimisation faite par le compilateur:
    Code 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    x=1e23
     
    a=int(x)
    print(id(a))
     
    b=int(x)
    print(id(b))
    Dans le code 2, les id sont les mêmes, alors que pas dans le code 1 !
    Exact. Effectivement et même sous P3. Et la différence commence à partir de "1e3"

    Joli exemple
    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]

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/02/2015, 13h30
  2. [Python 2.X] [python-constraints]ordre de parcours des variables
    Par fatbob dans le forum Bibliothèques tierces
    Réponses: 0
    Dernier message: 15/09/2014, 14h42
  3. Réponses: 11
    Dernier message: 26/06/2008, 02h34
  4. Portée des variables et pointeurs dans une procédure
    Par gicquairea dans le forum WinDev
    Réponses: 6
    Dernier message: 02/10/2007, 11h52
  5. Utiliser des variables avec Python et Gladfly ?!
    Par Exodus dans le forum Général Python
    Réponses: 5
    Dernier message: 17/09/2007, 09h49

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