Pyhton中函数传入的参数是变量值还是引用? 说实话,在这之前还没考虑过,因为直接返回就行,也是因为Python的特性, 变量可以指向任何类型的对象,所以就没太在意,等到遇到这道题后才发现是时候学习一下了。题目链接
Python中变量的特性
1 | |
直观上,一个变量可以随时的改变类型,这在C/C++中是不允许的。但是仔细探究Python语言的特性,变量可以看作是一个任何类型的特殊指针(当然在Python中是没有指针一说的,但是我们可以这样理解),它指向的对象没有限制,但是对象是确定的,即它本身可以是任何类型,但是对象的类型是固定的。
1 | |
下面着重结合上述的一个例子来讲述Python中函数的传值问题。
- 先看
test1()函数,发现我们把b1传进去,然后对b1[1]进行操作,然后在主程序中输出发现,函数内和函数外操作的对象是同一个(看输出的两个id一样,就表示在内存中存储的位置一样),这不禁让我想到C++中函数传入指针。 - 在看
test2()函数,我们这次直接对b2进行重新赋值,按照上面的分析,按我们应该得到新的b2,但是结果却是大相径庭,id不一样,而且b2的内容没有变化,这是什么情况?
现在,我们综合分析一下,Python中函数的形参到底是什么?先说答案吧,传入的是变量指向的对象的地址。
test1()中,当b1传入函数后,现在我们b1指向[0,1,2,3]的首地址,而val也同样指向[0,1,2,3]的首地址,下面的操作实际上并并没有让val指向的地址发生改变,只是修改了[0,1,2,3]对应位置上的值,所以从头至尾,b1和val指向同一个对象,你修改了val指向对象对应位置的值,等同于修改了b1指向的对象对应位置的值。test2()中,当b2传入函数后,b2和val同样指向相同对象的首地址,这个和上面一样,但是注意这里它是赋值操作,而这一操作改变了val指向的对象,本来val指向[0,1,2,3],现在一赋值,它就指向了[0,2,5]的首地址,这样本次操作,包括后面对val的操作对不会影响b2,可以说正是赋值操作使val和b2脱离了关系。
所以说,函数中对参数做的实际操作,决定了你是改变形参指向的对象(test1()),还是改变新生成的传入参数的副本(test2())。