Python浅拷贝和深拷贝
预备知识
1.对象的三个属性
python中每一个对象都有三个属性:唯一标志,类型和值。
其中对象的标志是一串数字,是每个对象的唯一标识,位于同一地址的对象标志相同。对象的值相等和标志相等判断方法如下:
id(s)查看对象的标志isis not判断两个对象的标志是否相同。==判断对象的值是否相同。
2.可变对象和不可变对象
“可变”,指改变对象的值后对象的标志(地址)是否会发生改变。改变可变对象(列表、字典、集合)的值,会在相应地址上关联数值,其标志不会改变;改变不可变对象的值,该对象的标志一定发生改变。
不可变对象:int、float、str、bool、tuple。
可变对象:list、dict、set。
#改变可变对象,其标志不变
a = [1, 2]
id(a)
Out[48]: 2407354182592
a.append(3)
id(a)
Out[50]: 2407354182592
浅拷贝
浅拷贝函数:a = copy.copy(x)。对象外层(父级)的拷贝,不拷贝内部(子级)。可以分为:
- x最外层不可变,则浅拷贝时:a会直接引用x的地址空间,id(a) == id(x)。
- x最外层可变,则浅拷贝时:会给a开辟一个新的地址空间,存放内层的标志,id(a) != id(x),但是内层标志不变,仍是原来的地址。
深拷贝
深拷贝函数:a = copy.deepcopy(x)。是对内层和外层的全部拷贝,与浅拷贝不同的是:
- x最外层不可变,里面是可变数据类型,会新开辟地址空间存放,id(a) != id(x),且内层也开辟新地址存放。
- x最外层型不可变,里面是不可变数据类型,则和浅拷贝不可变相同,id(a) == id(x)。
自己总结一下
如果把拷贝比作模仿秀,深和浅的区别在于是否能模仿到拷贝对象的灵魂(创建出一个新的标志),对象是可以嵌套的,所以灵魂有深层和浅层,深拷贝比较专业能够深入模仿,而浅拷贝只能模仿到表面。模仿的难度还由模仿的对象决定——可变对象和不可变对象。不可变的比较独特,灵魂难以模仿,仅外层不可变但是内层可变的对象才能被深拷贝完全模仿;如果内外都不可变,没有拷贝能够模仿。可变的就要好模仿很多,只要外层可变就能够给对象创建一个新地址,不过浅拷贝只能模仿到外层灵魂,而深拷贝可以递归模仿到深层。
嵌套可变对象深浅拷贝实例
# 内外层皆是可变对象
a = [1, 2]
b = [3, 4]
c = [a, b]
# 浅拷贝仅给外层创造一个新地址
d = copy.copy(c)
d is c
Out[29]: False
d[1] is c[1]
Out[30]: True
d[1].append(5)
d[1]
Out[34]: [3, 4, 5]
b
Out[35]: [3, 4, 5]
# 深拷贝会给内层和外层都开辟地址空间
e = copy.deepcopy(c)
e is c
Out[31]: False
e[1] is c[1]
Out[32]: False

浙公网安备 33010602011771号