Lorsque vous passez une collection comme list, array à une autre fonction en python, en fait-elle une copie, ou est-ce juste un pointeur?
Python transmet les références aux objets par valeur .
Python transmet les références aux objets par valeur (comme Java), et tout ce qui se trouve dans Python est un objet. Cela semble simple, mais vous remarquerez que certains types de données semblent présenter un passage -caractéristiques de la valeur, tandis que d'autres semblent agir comme un passage par référence ... quel est le problème?
Il est important de comprendre les objets mutables et immuables. Certains objets, comme les chaînes, les tuples et les nombres, sont immuables. Les modifier à l'intérieur d'une fonction/méthode créera une nouvelle instance et l'instance d'origine en dehors de la fonction/méthode ne sera pas modifiée. D'autres objets, comme les listes et les dictionnaires, peuvent être modifiés, ce qui signifie que vous pouvez modifier l'objet sur place. Par conséquent, la modification d'un objet à l'intérieur d'une fonction/méthode modifiera également l'objet d'origine à l'extérieur.
Le fait est que tout le concept de référence/valeur ne rentrera pas dans python. Python n'a pas de "valeur" de variable. Python n'a que des objets et des noms qui font référence à des objets).
Ainsi, lorsque vous appelez une fonction et mettez un "nom" entre parenthèses, 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 nommyname
lui-même. A l'intérieur de la fonction n autre nom (x
) est donné pour faire référence au même objet passé.
Vous pouvez modifier l'objet à l'intérieur de la fonction s'il est modifiable, mais vous ne pouvez pas changer ce vers quoi le nom extérieur pointe. C'est la même chose qui se produit quand vous le faites
anothername = myname
Je peux donc répondre à votre question par:
c'est "passer par valeur" mais toutes les valeurs ne sont que des références à des objets.
Les réponses ici ont été utiles, mais je trouve la nécessité de montrer cette fine distinction que je n'ai pas vu couverte, que je me suis prouvé avec l'expérience CL suivante:
'num' ne change pas ici car c'est un objet Number immuable [supporte mon point 1.]:
def incr_num(num):
num += 1
num = 0
num
0
incr_num(num)
num
0
'list [0]' est aussi ici un objet Number immuable.
def incr_list(list):
list[0] += 1
list = [0]
list[0]
0
incr_list(list)
list[0]
1
Alors, comment 'list [0]', étant un objet Number immuable, a-t-il changé (prend en charge mon point 2.) alors que l'objet Number 'num' de l'exemple ci-dessus n'a pas changé? L'objet Number immuable ' list [0] 'est contenu dans l'objet liste mutable' list ', tandis que' num 'du 1er exemple est juste un objet Number non contianed.
Bien que bien intentionnée, je pense @ Stephen Pape la réponse la mieux notée (citée ci-dessous), et certaines autres similaires, n'étaient pas totalement correctes (et cela m'a motivé à écrire cette réponse):
Certains objets, comme les chaînes, les tuples et les nombres, sont immuables. Les modifier à l'intérieur d'une fonction/méthode créera une nouvelle instance et l'instance d'origine en dehors de la fonction/méthode ne sera pas modifiée.
Ma deuxième expérience de code ci-dessus montre un objet Number ('list [0]') en cours de modification dans une méthode, puis l'instance d'origine en dehors de la fonction a changé.
Une référence est passée, mais si le paramètre est un objet immuable, sa modification dans la méthode créera une nouvelle instance.
L'objet est passé. Pas une copie, mais une référence à l'objet sous-jacent.
Je recommanderais également de regarder le module copy
:
documentation Python pour copie
Il vous aidera à comprendre les problèmes sous-jacents et à l'utiliser pour effectuer votre propre copie en profondeur.
Par référence:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
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 a = b 28331264 a après b = x 28329344 b après retour 28329344 var1 28331264 var2 ['1', '2', '3', '4'] ['20', "6", "7", "8", "9"]
Correspondance avec les adresses mémoire 28329344 28331264 var1 var2 abx Après a = ba Après b = xb Après a [0] = '20' [0] = '20' Après retour ['1', '2', '3', ' 4 '] [' 20 ',' 6 ',' 7 ',' 8 ',' 9 ']