python中的浅拷贝和深拷贝

来源:互联网 发布:网络黑白txt百度云盘 编辑:程序博客网 时间:2024/05/29 19:51

python中的浅拷贝和深拷贝

不得不说《python核心编程》是一本好书,看到其中一节做一下随笔。

浅拷贝

在python中,当创建一个对象后,然后把它赋给另一个对象时,python并没有去拷贝这个对象,而是拷贝了这个对象的引用。看不懂没关系,我们看一个例子。
>>>raw_list = ['first', ['second', 12], 32]>>>copy_list = raw_list[:]>>>copy_list[1][1] = 20>>>copy_list...['first', ['second', 20], 32]>>>raw_list...['first', ['second', 20], 32]>>>copy_list[2] = 50>>>raw_list...['first', ['second', 20], 32]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
上面代码可以很神奇的发现,我用切片复制的方法复制raw_list得到copy_list,然后第一次我去改变copy_list的值,然后raw_list也跟着发生改变。但是第二次我去改变copy_list,raw_list却没有发生变化。    这是因为,当进行浅拷贝的时候,字符串(firs)和数字(32)是不可被改变的并且被真实的复制了,并创建了新的对象,而列表(['second', 12])是可变的,只是把它的引用进行了复制,我们去改变列表的时候,他的引用都会发生变化。  进行浅拷贝有如下几种方式:1.完全切片操作[:],2.利用工厂函数,3.使用copy模块的copy函数。  

深拷贝

对于深拷贝来说,这相当与完完全全创建了一个新的对象,新的容器,我们看下面的例子
>>>import copy>>>raw_list = ['first', ['second', 12], 32]>>>copy_list = copy.deepcopy(raw_list)>>>copy_list[1][1] = 20>>>copy_list...['first', ['second', 20], 32]>>>raw_list...['first', ['second', 12], 32]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
可以看到,我们用copy.deepcopy()函数拷贝得到了copy_list,当我们改变copy_list的时候,raw_list并不会发生改变,因为深拷贝创建了一个新的对象。

注意事项

1.当操作数据,并且不想改变原数据的时候,使用深拷贝可能是个很好的选择。 
2.非容器类型(如数字,字符串等)没有被拷贝这一说法。 
3.只有原子类型的元组只有浅拷贝,没有深拷贝。