Confusion of Python function parameter passing

Since I have not studied Python systematically, many knowledge points are broken and cannot be formed as a whole. I always like to use other languages ​​to compare the syntax of Python. For example, for parameter passing, I always feel that Python will be divided into value passing and reference passing like C++ . I accidentally saw a blog post and realized that it was actually quite different.

First of all , Python's function parameter transfer, there is no difference between value transfer and reference transfer, because there is no way of calling by reference.

Secondly , even if it's all value passing, Python's value passing is different from C++'s value. There is no doubt about the value transfer method of C++, the value of the actual parameter will not change after the function call . In Python's value transfer method ( 这里姑且还是这样称呼它为值传递), the actual parameters may not change or change after the function is called . Let's look at the following example:

# 例子1
def test_int(input_value):
    input_value = 2

one_value = 1
test_int(one_value)
print('one_value = {
    
    }'.format(one_value))

The output of example 1 is:, the output of one_value = 1example 1 is easy to understand, what about example 2 below?

# 例子2
def test_list(input_list):
    input_list.append(3)

one_list = [1, 2]
test_list(one_list)
print('one_list = {
    
    }'.format(one_list))

The output of Example 2 is:, one_list = [1, 2, 3]why is the result different?

In fact, in Python, the type belongs to the object, and the variable has no type. The variable only points to the object : After the parameter is passed, the variables one_value and input_value both point to the object 1. You can refer to the following map:
Insert picture description here
(2 and 3 these objects are all systems Produced in advance for efficiency). Since the test_int()function body needs to 变量input_valuepoint to object 2, and then object 1 cannot be directly converted to object 2 (which can be understood as a constant object), then the variable input_value can only be changed to point to object 2, then the entire object structure will become as follows Form:
Insert picture description here
Therefore, when the function call returns, the variables one_valueand input_valuepoints to different objects. So the value of the variable one_value remains unchanged.

In example 2, the variables one_listand input_listboth point to the same list object:
Insert picture description here

Note that the list object itself can be changed. Adding an element to it will not re-create the object, but add new elements directly to the original object . Therefore, test_func2()after the call , the object structure is as follows:
Insert picture description here

one_listAnd input_liststill point to the same object, changing input_listthe value of one_listthe pointed object will indirectly change the value of the pointed object.

In the final analysis, after the function is called, if the formal parameter turns to point to another object, the change of the formal parameter will not affect the actual parameter; if the change of the formal parameter is directly operated on the original pointing object, the actual parameter of the formal parameter will still point to the same Object, the changes of formal parameters will be synchronized to the actual parameters.

Or, function parameter passing, it should be divided 不可变对象传递and 可变对象传递, strings, set, tuples, numbersis not subject to change, and list,dictso on it can be modified objects. When the function call is passed as an immutable object, even if the formal parameter is modified in the function body, the value of the actual parameter remains unchanged when the function call returns; if the function call is passed as a variable object, the formal parameter and actual parameter are modified in the function body Will follow and change.

After understanding the above reasons, the following situation is also easy to understand:

# 例子3
def test_tuple(input_tuple):
    input_tuple += (3, 4)

one_tuple = (1, 2)
test_tuple(one_tuple)
print('one_tuple = {
    
    }'.format(one_tuple))

The output of Example 3 is one_tuple = (1, 2).

Guess you like

Origin blog.csdn.net/xp178171640/article/details/115144126