86 votes

Que se passe-t-il lorsque vous affectez la valeur d'une variable à une autre variable en Python?

C'est mon deuxième jour de l'apprentissage de python (je connais les bases du C++ et certains de la programmation orientée objet.), et j'ai une légère confusion à l'égard de variables en python.

Voici comment je les comprends actuellement:

Python variables sont des références (ou pointeurs?) pour les objets (qui sont mutables ou immuable). Lorsque nous avons quelque chose comme num = 5, l'immuable objet 5 est créé quelque part dans la mémoire, et le nom-la référence de l'objet paire de num est créée dans un certain espace de noms. Lorsque nous avons a = num, rien n'est copié, mais maintenant, les deux variables font référence au même objet et a est ajouté au même espace de noms.

C'est là que mon livre, Automatiser les trucs ennuyeux avec Python, me confond. Comme c'est un débutant livre, il ne mentionne pas les objets, les espaces de noms, etc., et il tente d'expliquer le code suivant:

>>> spam = 42
>>> cheese = spam
>>> spam = 100
>>> spam
100
>>> cheese
42

L'explication qu'il propose est exactement la même que celle de C++ livre, dont je ne suis pas heureux à ce sujet que nous traitons avec des références/pointeurs vers des objets. Donc dans ce cas, je suppose que dans la 3e ligne, comme les entiers sont immuables, spam est attribué un tout nouveau pointeur/référence à un autre emplacement dans la mémoire, c'est à dire la mémoire qu'il a d'abord été pointant vers n'était pas modifié. C'est pourquoi nous avons cheese se référant à l'objet initial visé par l' spam. Est-ce la bonne explication?

88voto

Jonas Adler Points 5779

En tant que développeur C++, vous pouvez penser de Python variables comme des pointeurs.

Ainsi, lorsque vous écrivez spam = 100, cela signifie que vous "affecter le pointeur", qui était auparavant de pointage de l'objet 42, pour pointer vers l'objet 100.

Plus tôt, cheese a été attribuée à pointer vers le même objet que l' spam a souligné, ce qui est arrivé à être 42 à l'époque. Puisque vous n'avez pas modifié cheese, il reste des points de 42.

L'immutabilité n'a rien à faire avec elle, dans ce cas, puisque le pointeur de la cession ne porte pas de changer quoi que ce soit à propos de l'objet pointé.

25voto

enderland Points 3624

Il est correct, vous pouvez plus ou moins de variables que les pointeurs. Cependant l'exemple de code aiderait grandement à expliquer comment cela fonctionne.

Tout d'abord, nous allons fortement d'utiliser l' id fonction de:

De retour de "l'identité" d'un objet. C'est un entier qui est garanti pour être unique et constante pour cet objet pendant sa durée de vie. Deux objets avec des non-cumul des durées de vie peuvent avoir le même id() de la valeur.

Il est probable que ce seront de retour différentes valeurs absolues sur votre machine.

Considérons cet exemple:

>>> foo = 'a string'
>>> id(foo) 
4565302640
>>> bar = 'a different string'
>>> id(bar)
4565321816
>>> bar = foo
>>> id(bar) == id(foo)
True
>>> id(bar)
4565302640

Vous pouvez voir que:

  • L'original foo/bar ont des identifiants différents, parce qu'ils le point sur différents objets
  • Lorsque la barre est attribué à toto, leurs papiers d'identité sont désormais les mêmes. Ceci est similaire pour les deux pointant vers le même emplacement mémoire que vous voyez dans la réalisation d'un pointeur C++

lors du changement de la valeur de toto, il est affecté à un id différent:

>>> foo = 42
>>> id(foo)
4561661488
>>> foo = 'oh no'
>>> id(foo)
4565257832

Une observation intéressante, c'est que les entiers ont implicitement cette fonctionnalité jusqu'à 256:

>>> a = 100
>>> b = 100
>>> c = 100
>>> id(a) == id(b) == id(c)
True

Toutefois, au-delà de 256 ce n'est plus vrai:

>>> a = 256
>>> b = 256
>>> id(a) == id(b)
True
>>> a = 257
>>> b = 257
>>> id(a) == id(b)
False

cependant assigner a de b sera en effet de garder l'id est le même que celui montré avant:

>>> a = b
>>> id(a) == id(b)
True

21voto

plugwash Points 795

La façon dont je le vois il y a des vues différentes d'une langue.

  • La "langue de l'avocat" point de vue.
  • La pratique de "programmeur" point de vue.
  • le "réalisateur" de la perspective.

À partir de la langue de l'avocat perspective python variables toujours "point" d'un objet. Toutefois, contrairement à Java et C++, le behvaiour d' == <= >= etc dépend de l'exécution type des objets que les variables de point. En outre en python de gestion de la mémoire est gérée par la langue.

À partir d'une pratique programmeur perspective, nous pouvons traiter le fait que les entiers, les chaînes, tuples, etc sont immuables* les objets plutôt que directement des valeurs comme un détail sans importance. La seule exception est lorsque le stockage de grandes quantités de données numériques, nous pouvons utiliser des types qui peuvent stocker les valeurs directement (par exemple, des tableaux numpy) plutôt que les types qui vont se retrouver avec un tableau plein de références à des objets minuscules.

À partir d'un exécutants de la perspective de la plupart des langues ont une sorte de comme-si la règle telle que si les comportements sont corrects, la mise en œuvre est correcte, indépendamment de la façon dont les choses sont réellement sous le capot.

Donc oui, votre explication est correcte à partir d'une langue de l'avocat de la perspective. Votre livre est correct à partir d'une pratique programmateur de point de vue. Quelle mise en œuvre ne dépend de la mise en œuvre. Dans disponible entiers sont de véritables objets de si petite valeur entiers sont prises à partir d'un pool de cache plutôt que de créer de nouveau. Je ne suis pas sûr de ce que les autres implémentations (par exemple, pypy et jython) faire.

* noter la distinction entre mutable et des objets immuables ici. Avec un objet mutable nous devons être prudents au sujet de traiter "comme une valeur", parce que certains de code pourrait les transformer. Avec un objet immuable, nous n'avons pas de telles préoccupations.

17voto

David Heyman Points 954

Python est ni par référence ou par valeur. Python variables ne sont pas des pointeurs, ils ne sont pas des références, ils ne sont pas des valeurs. Python variables sont des noms.

Il pense que "passer par-alias" si vous avez besoin de la même phrase type, ou peut-être "passe-par-objet", parce que vous pouvez muter le même objet à partir de n'importe quelle variable qui indique, si c'est mutable, mais réaffectation d'une variable (alias) qu'une seule variable.

Si cela aide: C les variables sont des boîtes que vous écrivez des valeurs dans. Python noms sont les balises que vous avez mis sur les valeurs.

Un Python de la variable nom est un élément clé dans le global (ou local) de l'espace de noms, ce qui est effectivement un dictionnaire. La valeur sous-jacente est un objet de mémoire. Affectation donne un nom à cet objet. Affectation d'une variable à une autre variable signifie que les deux variables sont des noms pour le même objet. Ré-affectation d'une variable change de ce que l'objet est le nom de la variable sans changer l'autre variable. Vous avez déplacé le tag, mais pas modifié l'objet précédent ou toutes les autres balises sur elle.

Dans le sous-jacent C le code de la Disponible de la mise en œuvre, chaque objet Python est un PyObject*, de sorte que vous pouvez le penser comme un travail comme C si vous avez seulement eu des pointeurs vers les données (pas de pointeurs de pointeurs, pas directement les valeurs passées).

on pourrait dire que Python est passé par valeur, où les valeurs sont des pointeurs... ou vous pourriez dire que Python est passé par référence, où les références sont des copies.

11voto

Oleksandr Dashkov Points 1154

Lorsque vous exécutez spam = 100 python, créez un autre objet dans la mémoire, mais ne modifiez pas l'existant. donc vous avez toujours le pointeur cheese à 42 et spam à 100

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X