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())。