How do Python functions pass parameters?

 

a = [1,2,3]
def foo(b):
    b.append(4)
foo(a)
print(a)  #  [1,2,3,4]

def bar(c):
    c = [0,0,0]
bar(a)
print(a)  # [1,2,3,4]

Since it is said that passing by value or passing by reference, it is necessary to talk about C++ (as far as I know, these concepts are not in python). It is assumed that the subject and readers have some knowledge of C++. First review the concepts of actual parameters and formal parameters. Look at the foo function. Assuming this is a c++ function, then in the process of calling foo(a), a is the actual parameter and b is the formal parameter. If you are vague about this concept, take a good look at c The content of the part of function parameter transfer in ++primer will not be repeated here. Let's take a look at passing by value and passing by reference:

  • Passing by value is to copy the value of the actual parameter to the formal parameter as the value, and then the operation of the formal parameter in the function has nothing to do with the actual parameter. This is obviously not the way of passing parameters in python. Just look at the foo function. Understood, if the value is passed, b will copy a copy of [1,2,3], after executing b.append(4), it becomes [1,2,3,4], but the change of b will not affect a, In fact, a has also changed.
  • Passing by reference uses a formal parameter to give an alias to the actual parameter. The operation on the formal parameter in the function is actually the operation on the actual parameter. Let's give an example of passing by reference in C++:
//命名空间和头文件此处省略了
void test(vector<int>& vi)
{
       vi = vector<int>{ 0,0,0 };
}
int main()
{
       vector<int> v{ 1,1,1 };
       test(v); // 因为是传引用,执行结束后 v 变成了vector<int>{ 0,0,0 }
       return 0;
}

You can see that python is not by reference. Compare the bar function with the test function here. Note that after executing bar(a), a is not [0,0,0], and a has not changed, so there is an answer. I think it is wrong to say that mutable objects are by reference.

Therefore, neither by value nor by reference! In order to figure out how to pass parameters to a python function, it is essential to figure out the "name binding" in python. I try to use my own words to explain it more concisely. For more details, please refer to the link at the end. I call a, b, foo, bar these things as names instead of variables, because if you use an undefined thing xx, python will report NameError: name'xx' is not defined. In Python, name has no type, and the object pointed to by name has type. For example, name a can point to the object int number 1, or you can make it point to a list object. Consider the following code:

x = 1
y = x
print(y is x) #True 注意此处的is用来比较 y 与 x 所指向的对象是否为同一个,也就是id(x)与id(y)是不是一样的
# id方法返回的是某对象的id号(一个int值),在其生命周期内保证唯一和不变, id(x)就是返回x所指向的对象的id
y = 2
print(y is x) # False
x += 1 # 此时x的值为2,  x绑定到了对象 int2 上,同时id(x)也会发生改变 
print(y is x) # True 

x = 1 means that the object int 1 is bound (binging) with a name (name) called x, and the name x can be used to refer to the int 1 object. And y=x means that now y is also a name of the object int 1, and the name y can also be used to refer to the object int 1. And y and x are the name of the same object, so y is x returns True. Now y=2, y is x is False, because name x and y point to different objects. x+=1, at this time, note that id(x) will change, and the returned id is the id of the object int 2. Then if you execute y is x again, it will return True, because they all point to the object int 2.

Guess you like

Origin blog.csdn.net/weixin_51267929/article/details/114142342