python中的深拷贝和浅拷贝(读书笔记)
问题1 :为什么只设置了joe的值,但是jane的值也跟着变化呢?
原因:因为我们只做了一个浅拷贝,对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,其内容是原来对象元素的 | 引用 | 直白的说就是,新建了一个对象,但是它的内容 | 引用 | 原来的对象。
因为对象jane的内容引用自joe的内容,所以当joe的内容更改时,jane也随之更改。
序列类型对象的浅拷贝是默认类型拷贝,可以用以下几种方式实施
完全切片操作 利用工厂函数,比如list(), dict()等 使用copy模块的copy函数问题2: 为什么对设置wifey名字时,hubby的名字没有改变?
因为在person列表的两个对象中,第一个是字符串,不可变,第二个是可变的列表,当进行浅拷贝时,字符串被显式的拷贝,并新创建一个字符串对象,而列表元素,只是把它的引用复制了一下。
改变前
>>> id(x) for x in hubby >>> [4344118896, 4349387912] >>> [id(x) for x in wifey] >>> [4344118896, 4349387912] # 相同改变后
>>> id(x) for x in hubby >>> [4350395376, 4349387912] >>> id(x) for x in wifey >>> [4350586624, 4349387912] #列表第1个值的id已经不同,说明是另外创建了对象。要创建分离的对象,需要使用深拷贝
>>> person = ['name', ['saving', 100.0]] >>> hubby = person >>> import copy >>> wifey = copy.deepcopy(person) >>> [id(x) for x in person, hubby, wifey] >>> [4401609544, 4401609544, 4402474376] #可以看到,wifey的id已经不一样了 >>> hubby[0] = 'joe' >>> wifey[0] = 'jane' >>> hubby,wifey >>> (['joe', ['saving', 100.0]], ['jane', ['saving', 100.0]]) >>> hubby[1][1] = 50.00 >>> hubby,wifey >>> (['joe', ['saving', 50.0]], ['jane', ['saving', 100.0]]) # 此时,jane的saving不再随着joe改变 #验证一下id看是不是真的改变了 >>> [id(x) for x in hubby] >>> [4402580776, 4401564632] >>> [id(x) for x in wifey] >>> [4401200608, 4401248232] #四个对象都是不一样的了关于拷贝的警告 1 非容器类型(比如数字,字符串,和其他‘原子’类型的对象没有拷贝一说,浅拷贝是用完全切片来完成的,第二,如果元组变量,只包含原子类型对象,对它的深拷贝将不会进行,如果把person里第二个元素改成(),即使使用深拷贝也只能得到一个浅拷贝