首页 > 代码库 > python学习之copy模块

python学习之copy模块

copy模块中有两个方法,copy.copy()和copy.deepcopy,这两个方法分别是用来实现浅拷贝和深拷贝。所谓浅拷贝就是只拷贝引用,拷贝后生成的两个变量仍然是同一个对象,即其中一个变化了,另一个也跟着变化。而对于深拷贝,则是拷贝数据,生成的两个变量是不同的对象,他们之间的变化互不影响。但有一点要注意,copy模块的两个拷贝方法中针对的深浅拷贝说的是待拷贝对象的元素,即不管是copy()方法还是deepcopy()方法,待拷贝对象本身都是深拷贝,生成的是两个不同的对象,举个例子说明:

技术分享

可以看到,不管使用的是copy()方法还是deepcopy()方法,生成的都是不同的对象;但是如果使用copy()方法,则对象的元素如果是集合、类等可变类型,则是浅拷贝,而对象的deepcopy()是深拷贝。所以如果改变a1,则a2与a3都不会有影响;但是如果改变了a1的第一个元素,则a2的第一个元素会跟着变化,但是a3不会有影响,例如:

技术分享


注意事项:

1、对于内置类型的浅拷贝,一般不适用copy()函数,因为都有自己的工厂函数,而且效率要比copy()函数高很多,例如:list()、dict()、set()等

2、对于那些不可修改的对象(string, 数字, 元组,file,socket,module,method等),因为你不用担心修改他们,复制不复制也就没有什么大的意义了,所以使用"="、copy()、deepcopy()返回的都是同一个对象的引用,没有进行任何拷贝

3、deepcopy()有一个可选的字典,目的是跟踪受访问的对象,从而检测和避免重复定义的数据结构中的循环。比如list中包含了自身

4、尽管通常情况下不需要,但是通过实现方法__copy__(self)和__deepcopy__(self, visit),类就可以实现自定义的复制方法,这两个方法分别实现了浅复制和深复制操作。__deepcopy__()方法必须使用字典visit,用来在复制过程中跟踪前面遇到的对象。对于__deepcopy__()方法,除了将visit传到实现中包含的其他deepcopy()方法(如果有的话)之外,没有必要在执行其他操作。
如果类实现了pickle模块所用的方法__getstate__()和__setstate__(),那么copy模块将使用这些方法来创建副本,但是通过实现方法__copy__(self)和__deepcopy__(self, visit),类就可以实现自定义的复制方法,这两个方法分别实现了浅复制和深复制操作。

python学习之copy模块