目录
浅拷贝
深拷贝
总结:
首先说说赋值,赋值传递的是原始对象的地址,也就是说id是相同的。
# -*- codeing = utf-8 -*-
# @Time : 2022/10/31 21:10
# @Author : 可乐不加糖
# @File : copy_deepcopy.py
# @Software: PyCharm
list01 = [1, 2, 3, 4, 5, 6]
list02 = list01
print(f'list01:{list01},id:{id(list01)}')
print(f'list02:{list02},id:{id(list02)}')
结果:
list01和list02指向同一个地址,因此改变list01,list02也会发生变化,并且list02和list01的变化是一样的。
拷贝父对象,不会拷贝对象的内部的子对象。
# -*- codeing = utf-8 -*-
# @Time : 2022/10/31 21:10
# @Author : 可乐不加糖
# @File : copy_deepcopy.py
# @Software: PyCharm
from copy import copy
list01 = [1, 2, 3, 4, 5, [8, 9]]
list02 = list01.copy()
print(f'list01:{list01}, id:{id(list01)}')
print(f'list02:{list02}, id:{id(list02)}')
print('-------------------------------------------')
list01.append(10)
print(f'list01:{list01}, id:{id(list01)}')
print(f'list02:{list02}, id:{id(list02)}')
print('-------------------------------------------')
list01[5][0] = 7
print(f'list01:{list01}, id:{id(list01)}')
print(f'list02:{list02}, id:{id(list02)}')
运行结果:
首先,我们可以发现,list01和list02的id是不一样的, 这是因为使用浅拷贝后,list02会创建一个新的内存地址。
list01和list02是独立的,没有关联。
当向list01里面添加元素时或者进行其他操作时,list02都不会受到影响。
但是,当list01里面有可变类型的元素时(比如列表),改变list01的可变类型元素,list02就会受到影响。因为list01和list02都是将可变类型元素指向同一个地址。
python这样做可以减少内存的开销。
图解:
深拷贝不仅拷贝父对象,还会拷贝子对象。
# -*- codeing = utf-8 -*-
# @Time : 2022/10/31 21:10
# @Author : 可乐不加糖
# @File : copy_deepcopy.py
# @Software: PyCharm
import copy
list01 = [1, 2, 3, 4, 5, [8, 9]]
list02 = copy.deepcopy(list01)
print(f'list01:{list01}, id:{id(list01)}')
print(f'list02:{list02}, id:{id(list02)}')
print('---------------------------------------')
list01.append(10)
print(f'list01:{list01}, id:{id(list01)}')
print(f'list02:{list02}, id:{id(list02)}')
print('---------------------------------------')
list01[5][0] = 100
print(f'list01:{list01}, id:{id(list01)}')
print(f'list02:{list02}, id:{id(list02)}')
print('---------------------------------------')
同样,源对象和拷贝对象的id是不同的。
源对象和拷贝对象是完全独立的,没有任何关系。
当源对象是可变数据类型时,在堆内存中创建新的内存空间;当源对象是不可变数据类型时,拷贝引用地址。
list03 = 1
list04 = copy.deepcopy(list03)
print(f'list03:{list03}, id:{id(list03)}')
print(f'list04:{list04}, id:{id(list04)}')
print('---------------------------------------')
可以发现,深拷贝的源对象是不可变数据类型时,拷贝对象拷贝的是源对象的引用地址
图解: 当源对象是可变数据类型时:在堆内存创建新的内存空间。
当源对象是不可变数据类型是,拷贝引用地址:
浅拷贝和深拷贝都是对源对象的复制。
当源对象是单层时,源对象做任何改动,都不会影响浅拷贝和深拷贝。
当源对象是里嵌套可变数据类型时,源对象做任何改动,只会影响浅拷贝,不会影响深拷贝。