1, 浅拷贝
通过copy.copy(obj)进行浅拷贝时,拷贝的是子对象的引用
In [22]: my_list1 = ['a', 'b', 'c']
In [23]: my_list2 = copy.copy(my_list1)
In [25]: my_list1, my_list2
Out[25]: (['a', 'b', 'c'], ['a', 'b', 'c'])
# 可以看出my_list1, my_list2的子对象id都是一样的,即浅拷贝是完成的子对象引用的拷贝;值还是原来的值
In [26]: [id(x) for x in my_list1]
Out[26]: [1421561380400, 1421561368688, 1421560507440]
In [27]: [id(x) for x in my_list2]
Out[27]: [1421561380400, 1421561368688, 1421560507440]
1-1, 拷贝不可变对象
若子对象为不可变对象,则原始对象和拷贝对象是独立的,其中一项子对象的修改不会影响到另外一项
In [22]: my_list1 = ['a', 'b', 'c']
In [23]: my_list2 = copy.copy(my_list1)
In [25]: my_list1, my_list2
Out[25]: (['a', 'b', 'c'], ['a', 'b', 'c'])
# 由于my_list1中的子对象是不可变类型,所以修改my_list1的值,没有影响到my_list2
In [30]: my_list1[1] = 'fdsa'
In [31]: my_list1, my_list2
Out[31]: (['a', 'fdsa', 'c'], ['a', 'b', 'c'])
1-2, 拷贝可变对象
若子对象是可变对象,则原始对象和拷贝对象共享数据,即其中一项子对象的修改会影响到另外一项
# 子对象my_list1 [1][1]是可变类型
In [12]: my_list1 = ['a', ['b', 'c']]
# 浅拷贝
In [13]: my_list2 = copy.copy(my_list1)
# my_list1, my_list2的
In [14]: my_list1, my_list2
Out[14]: (['a', ['b', 'c']], ['a', ['b', 'c']])
# 子对象修改
In [18]: my_list1[1][1] = '1'
# 由于my_list1 [1][1]是可变类型子对象,所以修改my_list1的值会影响到my_list2
In [19]: my_list1, my_list2
Out[19]: (['a', ['b', '1']], ['a', ['b', '1']])
说明:浅拷贝相对于工厂方法或切片性能更好,对简单的数据拷贝推荐浅拷贝
2, 深拷贝
通过copy.deepcopy(obj)进行深拷贝, 拷贝的对象是全新的
2-1, 拷贝不可变对象
若原始对象的子对象为不可变类型,对其进行深拷贝是不会进行
In [39]: my_list1 = list('abc')
In [40]: my_list2 = copy.deepcopy(my_list1)
# 由于my_list1的子对象均为不可变,对其进行深拷贝不会进行,所以拷贝前后子对象的引用是一样的
In [41]: [id(x) for x in my_list1]
Out[41]: [1421561380400, 1421561368688, 1421560507440]
In [42]: [id(x) for x in my_list2]
Out[42]: [1421561380400, 1421561368688, 1421560507440]
2-2, 拷贝可变对象
若原始对象的子对象为可变类型,对其进行深拷贝后,原始对象和拷贝对象的数据是独立的,互不影响
In [43]: my_list1 = ['a', ['a', 'b']]
In [44]: my_list2 = copy.deepcopy(my_list1)
# 由于my_list1[1]是可变类型,所以进行深拷贝后,会生成新的对象
# 所以my_list1[1], my_list2[1]的引用不一致
In [45]: [id(x) for x in my_list1]
Out[45]: [1421561380400, 1421628105088]
In [46]: [id(x) for x in my_list2]
Out[46]: [1421561380400, 1421627951296]
# 深拷贝后,原始或拷贝对象的数据相互独立,互不影响
In [48]: my_list1[1][0] = 'aa'
In [49]: my_list1, my_list2
Out[49]: (['a', ['aa', 'b']], ['a', ['a', 'b']])