这一章节我们来讨论一下参数与共享引用
承接上一章节所说的参数的传递是通过自动将对象赋值给本地变量名来实现的,其本质就是复制引用,传递对象
1.我们下面以传递不可变对象为例子:
>>> b=1
>>> def test(x):
print(x)
print(id(x))
x=2
print(x)
print(id(x))
>>> test(b)
1
497734096
2
497734112
>>>
从代码可以看出,传递过程中x赋值了1这个对象的引用,只是把1赋值给b的引用复制一份给x,所以b与x的id都是相同的,引用相同内存地址
而当x修改变成2,只不过是重新创建一个对象,然后把引用赋值给x,所以x的id变了,也就是引用的对象变了
2.我们再来看看以可变对象为例子:
>>> b=1
>>> a=[1,2,3]
>>> def test(x,y):
print(x)
print(id(x))
x=2
print(x)
print(id(x))
print(y)
print(id(y))
y[1]=6
print(y)
print(id(y))
>>> test(b,a)
1
497734096
2
497734112
[1, 2, 3]
37586224
[1, 6, 3]
37586224
>>>
我们沿用上面的代码,然后在里面加上可修改对象,由结果可以看见,不可修改对象满足第一点的结论,但是,可修改对象就不一样,在整个运算过程中,a和y所引用的对象其实是没有改变,只是修改了对象里面的其中一个值,我们下面给出一个图片来说明
因为参数是通过赋值传递的,函数中的参数名可以调用时通过变了实现共享对象。因此,函数中对可变对象参数的在原处的修改能够影响调用者。
3.避免可变对象的修改
>>> b=1
>>> a=[1,2,3]
>>> def test(x,y):
print(x)
print(id(x))
x=2
print(x)
print(id(x))
print(y)
print(id(y))
y[1]=6
print(y)
print(id(y))
>>> test(b,a[:])#改动的地方
1
497734096
2
497734112
[1, 2, 3]
37588624
[1, 6, 3]
37588624
>>> a
[1, 2, 3]
或者我们在函数里面就已经进行复制,不需要再函数外操作
>>> b=1
>>> a=[1,2,3]
>>> def test(x,y):
print(x)
print(id(x))
x=2
print(x)
print(id(x))
t=y[:]#改变的地方
print(t)
print(id(t))
t[1]=6
print(t)
print(id(t))
print(y)
>>> test(b,a)
1
497734096
2
497734112
[1, 2, 3]
37108592
[1, 6, 3]
37108592
[1, 2, 3]
>>> a
[1, 2, 3]
>>>
总结:这一章节简单介绍了参数与共享引用,以及参数是可变对象时出现的问题和解决方案。
这一章节就说到这里,谢谢大家
------------------------------------------------------------------