Python浅拷贝和深拷贝

预备知识

1.对象的三个属性
python中每一个对象都有三个属性:唯一标志,类型和值。
其中对象的标志是一串数字,是每个对象的唯一标识,位于同一地址的对象标志相同。对象的值相等和标志相等判断方法如下:

  • id(s)查看对象的标志
  • is is 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

参考文章
python之深拷贝和浅拷贝
python中的深拷贝和浅拷贝

posted @ 2023-01-09 19:01  tree123  阅读(211)  评论(0)    收藏  举报