Python测试开发面试之深浅拷贝

发表于:2020-3-17 11:19  作者:测试轩   来源:博客园

字体: | 上一篇 | 下一篇 |我要投稿 | 推荐标签: 面试

  先来道题热热身
   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的地址相等")
  想想最后打印的是什么?
  什么是深拷贝和浅拷贝
  深拷贝,就是在对某个对象进行拷贝的时候,如果这个对象持有其他对象的引用,在拷贝的时候会将要拷贝的对象以及引用的对象,一起拷贝。
  而浅拷贝只拷贝当前对象和持有的索引,不拷贝索引指向的对象。举个例子说明一下,比如当前有个列表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]
  当深浅拷贝遇到可变与不可变对象时会发生什么
  上面用列表这种可变数据结构举例,再来看一下元组这种不可变结构,在进行深浅拷贝时定的现象。
   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语句都会执行。

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理

评 论

论坛新帖

顶部 底部


建议使用IE 6.0以上浏览器,800×600以上分辨率,法律顾问:上海瀛东律师事务所 张楠律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2020, 沪ICP备05003035号
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪公网安备 31010102002173号

51Testing官方微信

51Testing官方微博

扫一扫 测试知识全知道