Python中的passed by assignment与.NET中的passing by reference、passing by value

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python中的passed by assignment与.NET中的passing by reference、passing by value相关的知识,希望对你有一定的参考价值。

参考技术A

Python文档 中有一段话:

Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there’s no alias between an argument name in the caller and callee, and so no call-by-reference per se.

我们常说参数的传递分为按值传递与按引用传递,Python中的 passed by assignment 该如何理解?

stackoverflow 上关于paramter 和 argument的解释:

A parameter is a variable in a method definition. When a method is called, the arguments are the data you pass into the method\'s parameters.

When you pass a reference-type parameter by value, it is possible to change the data belonging to the referenced object , such as the value of a class member. However, you cannot change the value of the reference itself ; for example, you cannot use the same reference to allocate memory for a new object and have it persist outside the method. To do that, pass the parameter using the ref or out keyword. For simplicity, the following examples use ref .

In the preceding example, the array, arr , which is a reference type, is passed to the method without the ref parameter. In such a case, a copy of the reference, which points to arr , is passed to the method . The output shows that it is possible for the method to change the contents of an array element, in this case from 1 to 888 . However, allocating a new portion of memory by using the new operator inside the Change method makes the variable pArray reference a new array. Thus, any changes after that will not affect the original array, arr , which is created inside Main . In fact, two arrays are created in this example, one inside Main and one inside the Change method.

The following example is the same as the previous example, except that the ref keyword is added to the method header and call. Any changes that take place in the method affect the original variable in the calling program.

All of the changes that take place inside the method affect the original array in Main . In fact, the original array is reallocated using the new operator. Thus, after calling the Change method, any reference to arr points to the five-element array, which is created in the Change method.

Passing a value-type variable to a method by value means passing a copy of the variable to the method . Any changes to the parameter that take place inside the method have no affect on the original data stored in the argument variable. If you want the called method to change the value of the argument, you must pass it by reference, using the ref or out keyword. You may also use the in keyword to pass a value parameter by reference to avoid the copy while guaranteeing that the value will not be changed. For simplicity, the following examples use ref .

The variable n is a value type. It contains its data, the value 5 . When SquareIt is invoked, the contents of n are copied into the parameter x , which is squared inside the method. In Main , however, the value of n is the same after calling the SquareIt method as it was before. The change that takes place inside the method only affects the local variable x .

The following example is the same as the previous example, except that the argument is passed as a ref parameter. The value of the underlying argument, n , is changed when x is changed in the method.

In this example, it is not the value of n that is passed; rather, a reference to n is passed. The parameter x is not an int ; it is a reference to an int , in this case, a reference to n . Therefore, when x is squared inside the method, what actually is squared is what x refers to, n .

曾在Github上提过一个 issue ,用几幅图描述了按引用传递的情况。

说了这么多,Python中的passed by assignment该怎么理解?Python中类型没有像.NET那样分为值类型与引用类型。Python中所有类型的值都是对象,这些对象分为可变对象与不可变对象两种:

Python中,所有的数据类型都是对象,在传参时,传递的是对象的引用。与.NET中按值传递引用类型类似。对于不可变类型:

对于可变类型:

按值传递就是拷贝出变量值的一个副本,所有的操作都是针对这个副本的,对原始数据没有影响。

从下图中可以看到,按值传递引用类型,变量p2和p在内存中的地址不同,但存储的值相同:

按引用传递相当于给变量起了个别名,所有的操作都相当于操作原变量。从下图可以看到,按引用传递引用类型,p1和p在内存中的地址相同,存储的内容也相同:

对于按引用传递值类型和按值传递值类型,也是一样的:

Passing Parameters (C# Programming Guide)

Method Parameters (C# Reference)

The address-of operator

以上是关于Python中的passed by assignment与.NET中的passing by reference、passing by value的主要内容,如果未能解决你的问题,请参考以下文章

麻烦理解pass by reference

在Java里面谁能解释一下 pass by reference 还有pass by value?

C++ pass-by-non-const-reference 方法在 pass-by-const-reference 方法中

pass by value和pass by reference在C++中有啥区别?

值传递(pass-by-value)引用传递(pass-by-reference)以及函数与const关系

effective_c++条款20,用pass-by-reference-to-const替换pass-by-value