Passer des valeurs en Python [dupliquer]

cette question a déjà une réponse ici:

  • Comment passer une variable par référence? 23 réponses

quand vous passez une collection comme list, array à une autre fonction en python, est-ce que cela en fait une copie, ou est-ce juste un pointeur?

49
demandé sur Joan Venge 2009-02-11 00:51:43

8 réponses

Python transmet les références à des objets par valeur .

Python passe references-to-objects par valeur (comme Java), et tout en Python est un objet. Cela sonne simple, mais alors vous remarquerez que certains types de données semblent montrer caractéristiques de la valeur de passage, alors que d'autres agissent comme des passé par référence... quel est le problème?

il est important de comprendre mutable et des objets immuables. Certains objets, comme les chaînes, tuples et les nombres, sont immuable. Changement d'eux à l'intérieur d'un fonction/méthode permet de créer un nouveau instance et l'instance initiale en dehors de la fonction/méthode n'est pas modifié. Autres objets, comme des listes et les dictionnaires sont mutables, qui signifie que vous pouvez modifier l'objet en place. Ainsi, la modification d'un objet à l'intérieur d'une fonction/méthode aussi changer l'objet d'origine hors.

73
répondu Stephen Pape 2013-09-05 19:02:14

le truc c'est que, le concept de référence/valeur ne rentre pas dans python. Python n'a pas de "valeur" d'une variable. Python n'a que des objets et des noms qui font référence à des objets.

ainsi quand vous appelez une fonction et mettez un "nom" dans la parenthèse, comme ceci:

def func(x): # defines a function that takes an argument
    ... # do something here

func(myname) # calling the function

l'objet réel que myname pointe est passé, pas le nom myname lui-même . L'intérieur de la fonction un autre nom ( x ) est donné pour se référer au même objet passé.

vous pouvez modifier l'objet à l'intérieur de la fonction si elle est mutable, mais vous ne peut pas changer ce que le nom extérieur pointe à . Exactement la même chose qui se produit quand vous faites

anothername = myname

donc je peux répondre à votre question par:

c'est la" valeur de passage " mais toutes les valeurs sont justes les références à des objets.

66
répondu nosklo 2009-02-11 10:26:21

les réponses ici ont été utiles, mais je trouve le besoin de montrer cette distinction fine que je n'ai pas vu couvert, que je me suis prouvé avec L'expérience CL suivante:

  1. un objet immuable seul ne peut pas être modifié dans un appel de fonction. (réponses ont dit que beaucoup...)
  2. mais, un objet immuable contenu dans un objet mutable peut être réattribué dans le cadre d'une méthode appeler.

" num " ne change pas ici parce que c'est un objet Nombre immuable [supporte mon point 1.]:

def incr_num(num):
    num += 1

num = 0

num
0

incr_num(num)

num
0

'list[0]' voici un objet Nombre immuable aussi.

def incr_list(list):
    list[0] += 1

list = [0]

list[0]
0

incr_list(list)

list[0]
1

alors comment est-ce que 'list[0]', étant un objet Nombre immuable, change (supporte mon point 2.) alors que le numéro de L'objet 'num' de l'exemple ci-dessus ne l'a pas fait? L'immuable Numéro de l'objet " liste[0]' est contenu dans l'objet liste mutable 'list', tandis que' num ' du premier exemple est juste un objet Nombre non contiané.

bien que bien intentionnée, je pense que @Stephen Pape la réponse la mieux cotée (citée ci-dessous), et quelques autres similaires, n'étaient pas totalement correctes (et cela m'a motivé à écrire cette réponse):

Certains objets, comme les cordes, les tuples et les nombres, sont immuables. Changement d'eux à l'intérieur d'un fonction / méthode va créer une nouvelle instance et l'instance originale en dehors de la fonction/méthode n'est pas changée.

ma deuxième expérience de code ci-dessus montre un objet de nombre ('list[0]') étant modifié dans une méthode, puis l'instance originale en dehors de la fonction changée.

21
répondu cellepo 2017-05-23 12:34:23

une référence est passée, mais si le paramètre est un objet immuable, le modifier dans la méthode créera une nouvelle instance.

6
répondu anthony 2018-07-31 08:02:29

L'objet est passé. Pas une copie, mais une référence à l'objet sous-jacent.

4
répondu S.Lott 2009-02-10 21:53:42

je recommande également de regarder le copy module:

documentation Python pour copie

il vous aidera à comprendre les problèmes sous-jacents et comment l'utiliser pour effectuer votre propre copie profonde.

3
répondu Matt 2009-02-10 21:58:57

par référence:

>>> x = [0,1,2,3]
>>> def foo(x_list):
    x_list[0] = 1


>>> foo(x)
>>> x
[1, 1, 2, 3]
2
répondu Harper Shelby 2009-02-10 21:55:22

s'il vous Plaît permettez-moi de donner un humble exemple

def swap(a, b):
    x = a
    print id(x)
    print id(a)
    print id(b)
    a = b

    print id(a)
    b = x
    print id(b)
    a[0]= '20'




var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)

swap(var1, var2)

print id(var1)
print id(var2)
print var1
print var2

qui produit le résultat suivant

28329344 var1 28331264 var2 28329344 x 28329344 a 28331264 b Après un = b 28331264 a après b = x 28329344 b après le retour 28329344 var1 28331264 var2 ['1', '2', '3', '4'] ['20', '6', '7', '8', '9']

, Cartographie de la mémoire d'adresses 28329344 28331264 var1 var2 un b x Après un=b un Après b=x b Après un[0] = "20" [0] = "20" Après le retour ['1','2','3','4'] ['20', '6', '7', '8', '9']

0
répondu Antonio Leite 2012-10-22 10:26:54