http://blog.csdn.net/pipisorry/article/details/45830941
copy模块用于对象的拷贝操作。该模块只提供了两个主要的方法:copy.copy与copy.deepcopy,分别表示浅复制与深复制。
直接赋值:简单地拷贝对象的引用,两个对象的id相同。就是对象的引用(别名),就是给当前内存中的对象增加一个“标签”而已。通过使用内置函数 id() ,可以看出指向内存中同一个对象。
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。即浅复制只复制对象本身,没有复制该对象所引用的对象。A shallow copy constructs a new compound object and then (to the extentpossible) inserts references into it to the objects found in the original.
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。即创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。虽然实际上会共享不可变的子对象,但不影响它们的相互独立性。A deep copy constructs a new compound object and then, recursively, insertscopies into it of the objects found in the original.
浅拷贝和深拷贝的不同仅仅是对组合对象来说,所谓的组合对象就是包含了其它对象的对象,如列表,类实例。而对于数字、字符串以及其它“原子”类型,没有拷贝一说,产生的都是原对象的引用,所以两者就是一样的结果了。
直接赋值既不是浅拷贝也不是深拷贝!
>>> a = 3
>>> b = a
>>> b = 4
>>> a
3
>>> b
4
>>>
对组合对象来说,赋值后两者完全一样,相当于视图(numpy),没有copy到额外的空间中。
a = [1, 2, [3, 4]]
b = a
b[2][0] = 100
b[1] = 22
print(a)
print(b)
[1, 22, [100, 4]]
[1, 22, [100, 4]]
两个列表就是同一个列表,没有任何copy。
皮皮blog
字典的浅拷贝dict.copy()。
列表list的浅拷贝 assigning a slice of the entire list, copied_list = original_list[:];或者直接list1.copy()。
#coding=gbk
import copy
l1 = [1, 2, [3, 4]]
l2 = copy.copy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2
#---- 结果 ----
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]
[1, 2, [50, 4]]
如果list中没有引用其它对象,那么浅拷贝就和深拷贝一样一样了。
a = [1, 2, 3]
b = a.copy()
b[0] = 333
print(b)
print(a)
[333, 2, 3]
[1, 2, 3]
真正了解浅拷贝/深拷贝的示例。
a = [1, 3, [2, 3]]
b = a[:]
b[2][0] = 1999
b[1] = 2
print(b)
print(a)
[1, 2, [1999, 3]]
[1, 3, [1999, 3]]
深复制,不仅复制对象本身,同时也复制该对象所引用的对象。
import copy
l1 = [1, 2, [3, 4]]
l2 = copy.deepcopy(l1)
print l1
print l2
l2[2][0] = 50
print l1
print l2
#---- 结果 ----
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [3, 4]]
[1, 2, [50, 4]]
皮皮blog
浅拷贝:
>>>a = {1: [1,2,3]}
>>> b = a.copy()
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, b
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
深度拷贝:
>>>import copy
>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> a, c
({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})
1、b = a: 赋值引用,a 和 b 都指向同一个对象。
2、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。
b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。
皮皮blog
在定义类的时候,通过定义__copy__和__deepcopy__方法,可以改变copy的默认行为。下面是一个简单的例子:
class CopyObj(object):
def __repr__(self):
return "CopyObj"
def __copy__(self):
return "Hello"
obj = CopyObj()
obj1 = copy.copy(obj)
print obj
print obj1
#---- 结果 ----
CopyObj
Hello
from:http://blog.csdn.net/pipisorry/article/details/45830941
ref: [copy
— Shallow and deep copy operations]