面试官:什么是深拷贝和浅拷贝?

Time will tell.

1、先来道题热热身


a = ('a', 'b','c')
c = copy.copy(a)
d = copy.deepcopy(a)
 
if c == d:
     print("c和d的值相等")
if id(c) == id(d):
    print("c和d的地址相等")

想想最后打印的是什么?

.
.

2、什么是深拷贝和浅拷贝

深拷贝,就是在对某个对象进行拷贝的时候,如果这个对象持有其他对象的引用,在拷贝的时候会将要拷贝的对象以及引用的对象,一起拷贝。

而浅拷贝只拷贝当前对象和持有的索引,不拷贝索引指向的对象。举个例子说明一下,比如当前有个列表a = [1,2,3], b = [3,4,a],[3,4,a]对象持有了[1,2,3]对象的引用,在对b进行深拷贝的时候,会将a对象一起拷贝一份,而浅拷贝的时候则不会。


a = [1,2,3]
 
b = [4,5,6,a]

对b进行浅拷贝


c = copy.copy(b)

这个时候对a对象进行修改,会影响c


a.append(8)
 c
[4, 5, 6, [1, 2, 3, 8]]

对b进行深拷贝之后,再对a进行修改,则不会影响到d


d = copy.deepcopy(b)
 
d
[4, 5, 6, [1, 2, 3, 8]]
 
a.append(66)
 
 d
 [4, 5, 6, [1, 2, 3, 8]

3、当深浅拷贝遇到可变与不可变对象时会发生什么

上面用列表这种可变数据结构举例,再来看一下元组这种不可变结构,在进行深浅拷贝时定的现象。


a = (1,2,3)
b = copy.copy(a)
c = copy.deepcopy(a)
print(id(a))
print(id(b))
print(id(c))
 

输出:
4502776896
4502776896
4502776896



从结果中发现,a、b、c的内存地址大都是一样,所以在对不可变对象进行拷贝的时候,无论是浅拷贝还是深拷贝,都没有重新在内存中开辟新的地址,都只是对原对象增加了一个引用。

那如果不可变对象汇总包含有对可变对象的引用又会是怎么样呢?


a1 = [1,2,3]
a = (1,2,3, a1)
b = copy.copy(a)
c = copy.deepcopy(a)
print(id(a))
print(id(b))
print(id(c))

输出:
4502730288
4502730288
4503232240



b是浅拷贝生成的对象和原对象a的内存地址是一样对的,c是深拷贝生成的对象,发现内存地址和原对象a的地址是不一样的。

也就是说如果不可变对象中持有了可变对象的引用,在进行深拷贝的时候会在内存中开辟新的地址存放对象。

回到文章开头提出的问题,是对不可变对象进行拷贝,而且不可变对象中并没有持有可变对象的引用,所以两个print语句都会执行。



絮叨

如果你处于想学Python自动化或正在学习Python自动化中,Python自动化的教程不少了,但不一定是最新的,说不定你学的是别人一年前就学过的内容。干货分享一波!2020最新的Python教程。获取方式,加175317069私信Q群管理即可免费获取。

喜欢的话,欢迎【评论】、【点赞】、【关注】礼貌三连

Time will tell.(时间会证明一切)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值