En passant des valeurs en Python [dupliquer]
-
22-08-2019 - |
Question
Cette question a déjà une réponse ici:
Lorsque vous passez une collection comme la liste, un tableau à une autre fonction en Python, est-il une copie de celui-ci, ou est-ce juste un pointeur?
La solution
passe des références à des objets de valeur .
Python passe des références à des objets par valeur (comme Java), et tout Python est un objet. Cela semble simple, mais vous remarquerez que certains types de données semblent présenter transmettre par valeur, tandis que les caractéristiques d'autres semblent agir comme passage 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 des chiffres, sont immuable. les modifier dans un fonction / méthode va créer un nouveau instance et l'instance d'origine en dehors de la fonction / méthode ne modifié. D'autres objets, comme les listes et les dictionnaires sont mutable, qui signifie que vous pouvez changer l'objet en place. Par conséquent, la modification d'un objet à l'intérieur d'une fonction / méthode volonté modifier également l'objet d'origine extérieur.
Autres conseils
La chose est, le concept de référence / valeur ne rentrera pas dans python. Python n'a pas de « valeur » d'une variable. Python a des objets seulement et les noms qui font référence à des objets.
Alors, quand vous appelez une fonction et mettre une parenthèse dans la « nom », comme ceci:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
L'objet réel qui myname
pointe est passé, pas le nom myname
se . A l'intérieur de la fonction un autre nom (x
) est donné de se référer au même objet passé.
Vous pouvez modifier l'objet dans la fonction si elle est mutable, mais vous ne peut pas changer ce nom en dehors pointe vers . Tout de même ce qui se passe quand vous faites
anothername = myname
Par conséquent, je peux répondre à votre question:
il est "passe par la 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 présenter cette distinction bien que je ne l'ai pas vu couvert, que je suis à moi-même éprouvé avec l'expérience suivante CL:
- Un objet immuable NE PEUT PAS SEULS être modifiée dans un appel de fonction. (réponses à ce jour ont dit que beaucoup ...)
- MAIS, un objet immuable CONTENUES un objet mutable PEUT être réaffecté dans un appel de méthode.
'num' ne change pas ici parce qu'il est un objet immuable Nombre [supporte mon point 1.]:
def incr_num(num):
num += 1
num = 0
num
0
incr_num(num)
num
0
'liste [0]' est un objet immuable Nombre ici aussi.
def incr_list(list):
list[0] += 1
list = [0]
list[0]
0
incr_list(list)
list[0]
1
Alors, comment « liste [0] », étant un objet Nombre immuable, le changement (prend en charge mon point 2.) tandis que l'objet numéro d'exemple ci-dessus « de num » n'a pas? L'objet Nombre immuable « liste [0] » est contenu dans la « liste » objet de la liste mutable, tandis que « num » à partir du 1er exemple est juste un objet Numéro non contianed.
Bien que bien intentionnée, je me sens @Stephen Pape réponse top-rated (cité ci-dessous), et quelques-uns d'autres semblables, ne sont pas tout à fait correct (et qui m'a poussé à écrire cette réponse):
Certains objets, comme des cordes, des tuples et des chiffres, sont immuables. les modifier dans une fonction / méthode va créer une nouvelle instance et l'instance d'origine en dehors de la fonction / méthode ne change pas.
Mon 2ème expérience de code ci-dessus montre un objet Number ( « liste [0] ») étant modifiée dans une méthode, puis l'instance d'origine en dehors de la fonction a changé.
Une référence est passé, mais si le paramètre est un objet immuable, la modifier à l'intérieur de la méthode va créer une nouvelle instance.
L'objet est passé. Pas une copie, mais une référence à l'objet sous-jacent.
Je recommande également regarder le module copy
:
documentation Python pour la copie
Il vous aidera à comprendre les problèmes sous-jacents et comment 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 laissez-moi donner un exemple humble
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 une 28331264 b Après = b 28331264 une après b = x 28329344 b après le retour 28329344 var1 28331264 var2 [ '1', '2', '3', '4'] [ '20', '6', '7', '8', '9']
cartographie des adresses de mémoire 28329344 28331264 var1 var2 un B X Après = b une Après b = x b Après une [0] = '20' [0] = '20' après le retour [ '1', '2', '3', '4'] [ '20', '6', '7', '8', '9']