Python函数参数传递

Python中函数参数的传递是采用传值方式,但是和C/C++有所不同

C/C++方式

void fun(int a)
{
    a = 10;
}

void main()
{
    int c =3;
    fun(c);
}

上面示例,c最终的值是3.因为c是将3这个值传递给了fun,其本身的值没有变。fun函数在使用3这个值时,又申请了一个临时的存储空间,这个存储空间在调用函数结束后被销毁。

void fun(int *a)
{
    *a = 10
}

void main()
{
    int c =3;
    fun(&c);
}

上面的示例,c最终的值是10.函数还是采用传值的方式,但是以为定义的是指针变量,所以fun函数认为传递的值是一个地址。修改指针变量指向的存储空间地址的内容,也就是修改c的内容。

Python的方式

变量 VS 类型

python的变量是没有类型的,所有的变量可以理解成是内存中一个对象的“引用”,用c来表示就是 void *。所以并不像c语言里面有某某类型变量的说法。比如

int a =1;

上面可以表述为 a 是一个int型变量

a  = 1

上面不能像c那样理解。a只是一个“指针”,这个“指针”指向一个int型的对象

可更改(mutable)与不可更改(immutable)对象

在Python中,strings,numbers,tuples是不可更改对象,list,dict是可更改对象。对比c语言理解

int a = 1;
a =2;
a = 1
a = 2

两种方式a最终的结果都是2.但是处理方式是不一样的。在c语言中,是给a申请了一个存储空间,并给这个存储空间赋值为1,随后改成2.在python中,是在内存中建立一个值为1的对象,并使a“指向”它,随后赋值为2的时候,并不是修改这个值为1的对象,而是将其抛弃。重新申请一个值为2的对象,并使a“指向”它。这是因为numbers对象是不可更改的

a = [1]
a[0]=2

同理,这里构建了一个list对象,并使a指向它,但是因为list对象是可以改变的。所以list的第0个元素的值发生了改变。用c链表表述的话,就是原来指向int型变量值为1的指针重新定向到了指向int型变量的值为2的指针。

typedef list int *;
int a[3] ={1};
list = a;
*(list) = 2;

可以看到list并没有

赋值与引用

a = 4
 b = a
 b = 5

上面脚本的输出结果为:

a = 4 b =5

a = [3,4]
b = a
b[0] = 10

上面的脚本输出结果

a = [10 ,4] b =[10 , 4]

可以看出,number是赋值,而列表是引用。

Python函数传值

所以结果很明显了,当传递immutabble对象时,被传递对象无法被改变,当传递mutable时,被传递对象可以被改变。

def fun(a):
    a = 10

b = 2
fun(b)

当b传递给fun时,a和b都指向2这个不可更改的对象。当fun函数给a赋值,因为对象不可更改,所以只能新建一个对象,并将a重新指向它,而b的值并没有改变。

def fun(a):
    a[0] = 10

b = [2]
fun(b)

同上,但是list对象是可以被改变的,a和b同时指向了这个list对象,所以在fun函数中发生的修改,使b指向的list的值发生了改变。

原文地址:https://www.cnblogs.com/WeyneChen/p/6670644.html