Python - 深浅复制的区别

Python 中的数据类型是否可变分类依据是你修改这个变量的时候修改的是内存指针还是内存地址里的值。

不可变数据类型修改变量的值时,实际上只是修改了这个变量的指针。而可变数据类型的变量则是内存地址不变,修改了该地址的值。

在可变数据类型的使用与复制时要额外注意这点。

>>> numbs1 = [100, 200, 300]
>>> numbs2 = numbs1
>>> numbs1[0] = 1
>>> print(numbs2)
[1, 200, 300]
>>> id(numbs1)
140071119138240
>>> id(numbs2)
140071119138240

深浅复制的区别主要应用于可变数据类型里的列表、字典、集合。

浅复制在复制的时候新的对象指向的内存地址与原对象不同,但是对象内的元素指向的内存地址是相同的。

>>> numbs1 = [100, 200, 300]
>>> numbs2 = numbs1
>>> numbs1[0] = 1
>>> print("%X %X" %(id(numbs2),id(numbs2)))
7F465477ED00 7F465477ED00
>>> numbs3 = numbs1.copy
>>> print("列表的内存地址%X %X %X" %(id(numbs1),id(numbs2),id(numbs3)))

列表的内存地址7FAB8520E180 7FAB8520E180 7FAB8520E380

>>> print("列表中第一个元素的内存地址%X %X %X" %(id(numbs1[0]),id(numbs2[0]),id(numbs3[0])))

列表中第一个元素的内存地址558984E25D40 558984E25D40 558984E25D40
而深复制则会将对象内的元素也完全复制到其他地址上。是一种完全拷贝。
# import copy ; z = copy.deepcopy (x)

踩过的坑

在开发猴面雀的时候是真真实实的踩过这个坑。
具体代码就不贴出来了,简单讲述一下流程。
业务流程是从物品目录中将物品的信息与制作配方复制出来,在配方的基础上反复查询递归计算每个材料的价值,最终计算出制作这个物品的总价。
结果在复制的时候没有采用深复制,递归计算的过程直接污染了物品目录中的原始数据,最终结果会随着每次查询膨胀几十倍。
在debug的时候找了三四天的根因,最后把问题锁定在了原始数据会变化的这点。把所有复制数据的部分改成了深复制才解决这个BUG。

posted @ 2023-04-18 11:08  NagaResst  阅读(31)  评论(0)    收藏  举报