1、python的引用
Python参数传递采用的是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值”来传递对象。
2、copy与deepcopy
从上面的程序中,可以发现:
在进行复制后,copy与deepcopy的id都已经发生了变化,即他们不再指向同一个引用,表明其对父对象都进行了拷贝,不同的是copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象,copy.deepcopy 深拷贝 拷贝对象及其子对象。使用“=”,则id相同,这就意味着对b或a做的任何改动,都会彼此影响,所以下面只讨论a的变化对c,d的影响。
那么当我们对a进行改变时,会发生什么呢?
可以看到,c和d完全没有变化。
接下来我们在对a进行改变:
在我们对a中的可变子对象进行改变时,可以发现c中的值也发生了改变,a[1]是一个列表,是一个可变的对象,对其进行append时,只是改变了里面的元素值,并没有改变引用对象,可以从下面的代码中看出:
可以发现,虽然同为可变对象,但是a[1]和 c[1]的id是一样的,但是d中的id已经发生了变化。所以当a中的a[1]改变了以后,c中自然会改变,同理,当对c中的c[1]进行改变时,a和b中也会改变。而从这里也可以发现deepcopy之后,子对象的引用也发生了变化。
而如果对不可变的子对象进行改变时,如a[0],c则不会发生变化:
原理也很简单,a[0]是一个int,不是可变对象,在对其进行改变时,则引用也会发生相应的改变。