En Python, je résumerai la manipulation (stratégie d'évaluation) lors du passage d'arguments aux fonctions et aux méthodes objet. Comme expliqué dans À propos des variables et objets Python, en Python, toutes les valeurs sont des objets et les variables stockent des références d'objets (références). Ça a été. Lorsqu'une fonction est appelée, vous pouvez la considérer comme une référence de l'argument réel (argument de l'appelant) "copié" dans l'argument factice (argument de la fonction) et passé. Cette méthode est appelée «appel par partage» ou «appel par valeur où valeur est la copie de référence».
En Python, si vous réaffectez une autre valeur à un argument dans une fonction et modifiez la référence ou la référence de la variable, elle ne sera pas reflétée à l'appelant. Tout d'abord, considérons le cas de la transmission d'une variable de valeur immuable telle qu'une valeur numérique ou une chaîne de caractères comme argument. Dans l'exemple suivant, 10 est ajouté à la valeur de l'argument arg dans la fonction test1 (). Il crée en fait un nouvel objet entier avec la valeur de l'argument plus 10 et réaffecte sa référence à la variable arg.
def test1(arg):
arg += 10 #① Ajouter 10 à la valeur de arg et réaffecter
num = 3
test1(num)
print(num) #② Afficher la valeur de num
Après avoir appelé la fonction test1 (), si vous essayez d'afficher la valeur de la variable num en dehors de la fonction ②, le changement de la valeur de l'argument à l'intérieur de la fonction ① n'est pas reflété.
$ python3 arg_test1.py
3 ← ② La valeur de la variable num reste "3"
Cela est dû au fait que la destination de référence de l'argument arg a été modifiée en la réaffectant à l'argument arg dans (1). Avant l'exécution de ①, la variable globale num en dehors de la fonction et l'argument arg se réfèrent à la même valeur, mais après ①, ils se réfèrent à des valeurs différentes. Vous pouvez vérifier que la référence a changé avec la fonction id () qui affiche le numéro d'identification de l'objet comme suit.
def test1(arg):
#Changer les arguments à l'intérieur de la fonction
print("arg: {}".format(id(arg)))
arg += 10 # ①
print("arg: {}".format(id(arg)))
num = 3
test1(num)
print(num) #Afficher la valeur de num
Le résultat de l'exécution sera le suivant
$ python3 arg_test1.py
arg:4297537952 ← Avant ①
arg:4297538272 ← ID changé après ①
3 ← La valeur de la variable num reste la même en dehors de la fonction
La même chose est vraie lors du passage d'une valeur modifiable telle qu'une liste ou un dictionnaire en tant qu'argument, et si la référence change, elle ne sera pas reflétée à l'appelant. Dans l'exemple suivant, la liste est passée en argument, un élément est ajouté par "arg + [4, 5]" à l'intérieur de la fonction et il est réaffecté à arg.
def test2(arg):
#Changer les arguments à l'intérieur de la fonction
print("arg: {}".format(id(arg)))
arg = arg + [4, 5] #① Ajouter un élément
print("arg: {}".format(id(arg)))
myLst = [1, 2, 3]
test2(myLst)
print(myLst) #Afficher la valeur de myLst
Dans ce cas (1), la référence change car un nouvel objet de liste est créé en combinant "[4, 5]" avec l'opérateur "+". Par conséquent, il n'est pas reflété dans l'appelant.
$ python3 arg_test2.py
arg: 4329564104
arg:4329566024 ← ID changé
[1, 2, 3]← La valeur ne change pas en dehors de la fonction
Si vous passez une valeur mutable comme argument et que la référence n'est pas modifiée dans la fonction, la modification de la fonction sera répercutée sur l'appelant. Par exemple, si vous exécutez une méthode qui modifie directement la valeur d'un objet. Dans l'exemple suivant, l'élément est ajouté à la liste par la méthode extend () au lieu de l'opérateur "+" dans l'exemple précédent dans ① à l'intérieur de la fonction. De plus, dans ②, le deuxième élément de la liste est changé en "10" par "arg [1] = 10".
def test3(arg):
#Changer les arguments à l'intérieur de la fonction
print("arg: {}".format(id(arg)))
arg.extend([4, 5]) # ① [4, 5]Ajouter
arg[1] = 10 #② Changer le deuxième élément
print("arg: {}".format(id(arg)))
myLst = [1, 2, 3]
test3(myLst)
print(myLst) #Afficher la valeur de myLst
Dans ce cas, la référence ne change pas car aucun nouvel objet n'est créé dans ①②. Par conséquent, les modifications de la valeur des arguments à l'intérieur de la fonction seront reflétées dans l'appelant.
$ python3 arg_test3.py
arg: 4321175496
arg:4321175496 ← L'identifiant ne change pas
[1, 10, 3, 4, 5]
Recommended Posts