在python的学习过程中,遇到浅拷贝和深拷贝的问题。
一.分别赋值、浅拷贝和深拷贝的结果(单纯进行赋值或拷贝,不进行改变)
上图中,will是要拷贝的对象,而willber则是拷贝的结果。
可以看到:
1.赋值操作没有产生新对象,而两种拷贝都产生新对象。
2.对于浅拷贝,不论原对象元素是不可变(数字和字符串)还是可变(列表或字典),都是相同的引用,指向相同的对象。
对于深拷贝,拷贝的是对象值。对于容器类的元素,产生新的对象;非容器类的元素,还是相同的对象。
二.对赋值或拷贝的结果进行修改,观察对原对象的影响
接下来,对赋值或拷贝的结果进行修改,修改列表中中的第一个元素(字符串)和最后一个元素(列表)。得到的结果如下:
可以看到:
1.对于赋值结果的修改,同时修改原对象和当前对象(因为两者具有相同的引用,指向同一个元素)
2.对于浅拷贝结果的修改,如果元素是不可变对象,则不改变原对象的值(如字符串,例子列表中的第一个元素);
如果元素是可变对象,则同时改变原对象和本身(如列子中的第三个元素)
3.对于深拷贝结果的修改,不论元素是可变对象还是不可变元素,都不改变原对象
三.总结
对于赋值,相当于增加了对同一对象的引用,所以每次修改都会导致原变量的变化(因为指向相同的对象,修改也是在这个对象上进行的)
对于浅拷贝,产生了新对象(变量的id值不同)。拷贝的是引用值。新对象的元素与原对象元素具有相同的引用(不管是可变元素还是不可变元素)。如果要修改的元素是不可变对象(如数字,字符串),引用的对象产生了变化(数字或字符串),只改变拷贝的结果,不改变要拷贝对象的值(因为两者引用的对象不一样);如果要修改的元素是可变对象(如列表,字典),由于拷贝的是引用,同时元素是可变的,所以会对这个元素对象进行修改,导致原对象亚发生改变。
对于深拷贝,也产生了新对象。拷贝的是对象值(不是引用值)。对于元素的修改,不会影响原对象(因为两者引用对象不一样)