In Python, the handling (Evaluation strategy) when passing arguments to functions and object methods is summarized. As explained in About Python Variables and Objects, in Python all values are objects, and variables store object references (references). It has been. When a function is called, you can think of it as a reference of the actual argument (caller's argument) being "copied" to the formal argument (function's argument) and passed. This method is called "call by sharing" or "call by value where value is the reference copy".
In Python, if you reassign another value to an argument inside a function and change the reference or reference of the variable, it will not be reflected to the caller. First, let's consider the case of passing a variable with an immutable value such as a numerical value or a character string as an argument. In the following example, 10 is added to the value of the argument arg inside the function test1 (). It actually creates a new integer object with the value of the argument plus 10, and reassigns its reference to the variable arg.
def test1(arg):
arg += 10 #① Add 10 to the value of arg and reassign
num = 3
test1(num)
print(num) #② Display the value of num
After calling the function test1 (), when the value of the variable num is displayed outside the function ②, the change in the argument value inside the function ① is not reflected.
$ python3 arg_test1.py
3 ← ② The value of the variable num remains "3"
This is because the reference destination of the argument arg has been changed by reassigning it to the argument arg in (1). Before ① is executed, the global variable num outside the function and the argument arg refer to the same value, but after ①, they refer to different values. You can check that the reference has changed with the id () function that displays the ID number of the object as follows.
def test1(arg):
#Change arguments inside the function
print("arg: {}".format(id(arg)))
arg += 10 # ①
print("arg: {}".format(id(arg)))
num = 3
test1(num)
print(num) #Show value of num
The execution result will be as follows
$ python3 arg_test1.py
arg:4297537952 ← Before ①
arg:4297538272 ← ID changed after ①
3 ← The value of the variable num remains the same outside the function
The same is true when passing a mutable value such as a list or dictionary as an argument, and if the reference changes, it will not be reflected to the caller. In the following example, the list is passed as an argument, the element is added by "arg + [4, 5]" inside the function, and it is reassigned to arg.
def test2(arg):
#Change arguments inside the function
print("arg: {}".format(id(arg)))
arg = arg + [4, 5] #① Add element
print("arg: {}".format(id(arg)))
myLst = [1, 2, 3]
test2(myLst)
print(myLst) #Display the value of myLst
In this case (1), the reference changes because a new list object is created by combining "[4, 5]" with the "+" operator. Therefore, it is not reflected in the caller.
$ python3 arg_test2.py
arg: 4329564104
arg:4329566024 ← ID changed
[1, 2, 3]← The value does not change outside the function
If you pass a mutable value as an argument and the reference is not changed in the function, the change in the function will be reflected in the caller. For example, when you execute a method that directly changes the value of an object. In the following example, the element is added to the list by the extend () method instead of the "+" operator in the previous example in ① inside the function. Also, in ②, the second element of the list is changed to "10" by "arg [1] = 10".
def test3(arg):
#Change arguments inside the function
print("arg: {}".format(id(arg)))
arg.extend([4, 5]) # ① [4, 5]Add
arg[1] = 10 #② Change the second element
print("arg: {}".format(id(arg)))
myLst = [1, 2, 3]
test3(myLst)
print(myLst) #Display the value of myLst
In this case, the reference does not change because no new object is created in ①②. Therefore, changes in the argument values inside the function are reflected in the caller.
$ python3 arg_test3.py
arg: 4321175496
arg:4321175496 ← ID does not change
[1, 10, 3, 4, 5]
Recommended Posts