python中函数传参过程
- 值传递
值传递实际上就是把实际参数值的副本传入函数,不管函数对该值做了什么操作,而参数本身不会受到任何影响。
def func(a, b):
a, b = b, a
print("func里交换处理完a的值为{},b的值为{}".format(a, b))
if __name__ == '__main__':
a, b = 3, 4
print("交换前a的值为{},b的值为{}".format(a, b))
func(3, 4)
print("交换后a的值为{},b的值为{}".format(a, b))
# 结果
'''
交换前a的值为3,b的值为4
func里交换处理完a的值为4,b的值为3
交换后a的值为3,b的值为4
'''
通过上面的例子,看出值传递的实质是当系统开始执行函数时,系统对形参执行初始化,就是把实参变量的值赋值给函数的形参变量,在函数中操作的并不是实际的实参变量,而是复制的副本。
- 引用传递
果果实际参数的数据类型是可变对象(列表,字典、元组、集合等),则函数传递方式将采用引用传递的方式。而引用传递方式的低层实现,采用的依然还是值传递的方式。
# 把字典中的key为a和b所对应的值交换
def func(d):
d['a'], d['b'] = d['b'], d['a']
print("func里交换处理a元素的值为{},b元素的值为{}".format(d['a'], d['b']))
if __name__ == '__main__':
d = {'a':3, 'b':4}
print("交换前a元素的值为{},b元素的值为{}".format(d['a'], d['b']))
func(d)
print("交换后a元素的值为{},b元素的值为{}".format(d['a'], d['b']))
# 结果
'''
交换前a元素的值为3,b元素的值为4
func里交换处理a元素的值为4,b元素的值为3
交换后a元素的值为4,b元素的值为3
'''
在上面例子中,a元素与b元素的值交换成功,func函数执行完,主程序中字典d的a元素和b元素的值也发生了交换,这很容易造成错觉。实际上,程序开始创建了一个字典对象,并定义了一个d的引用变量(其实就是一个“指针”)指向字典对象,现在内存中有对象本身和指向该对象的引用变量;然后,主程序调用func函数,d变量作为参数传入,把主程序中d变量的值赋给func函数的形参d(这里仍然是值传递),同时把指向这个字典对象的地址值也传进来,他们引用的是同一个字典对象;于是,在func函数中对d这个引用变量进行交换操作时,就等于对这个字典对象进行操作,所以主程序中d变量所引用对象的a元素和b元素的值也被交换。
总而言之:
- 不管什么类型的参数,在python函数中对参数直接使用"="等号赋值方式是诶用的,并不能改变参数的值。
- 把这些数据包装成列表、字典等可变对象,然后传参到函数里进行修改,这样数据会发生改变。