Python 引用(Reference)& 浅拷贝(Shallow copy) & 深拷贝(Deep copy)

在阐述引用、浅拷贝和深拷贝前,首先需要要了解 Python 的世界里,一切皆对象,每个对象各包含一个 idendity、type 和 value。如下图所示,id 、type 均为不可变的;value即可为可变的,也可为不可变的。 

1、引用 (Reference) 

>>> b = [1 , 2]
>>> a = [b, 3, 4]
>>> c = a  # c = a 表示 c 和 a 指向相同的地址空间,并没有创建新的对象。 
>>> print(c)
[[1, 2], 3, 4]
>>> id(a)
4408148552
>>> id(c)
4408148552

 

2、浅拷贝(Shallow Copy) 

d = copy.copy(a)  是浅拷贝~~~虽然它有两个copy...等价于 d = a.copy()
浅拷贝只会拷贝父对象,不会拷贝父对象中的子对象,所以若a的子对象变,则d变;但是父对象变,d不会改变。

 

>>> import copy
>>> d = copy.copy(a)  # 创建了一个新对象,复制了原有对象的引用
>>> print(d)
[[1, 2], 3, 4]

>>>
>>> id(d)  # d 和 a 的地址不一样
4408199792
>>> id(a)
4408148552
>>>
>>> id(a[0])  # a[0] 和 d[0]地址一样,即子对象地址一样
4408022944
>>> id(d[0])
4408022944

>>> d[0][0] = 5 #子对象改变,则两者都改变
>>> print(d)
[[5, 2], 3, 4]
>>> print(a)   # 由于a[0] 和 d[0]地址一样,则改变 d[0][0]的值,对a[0][0]有影响。
[[5, 2], 3, 4]


>>>
>>>id(a[1])  # a[1] 和 d[1]地址不一样
1997107680
>>>id(d[1])
1997106720
>>> a[1] = 33  # 父对象的改变,d不会改变
>>> print(a)
[[5, 2], 33, 4]
>>> print(d)  # 由于a[1] 和 d[1]地址不一样,则改变 a[1]的值,对 d[1]无影响。
[[5, 2], 3, 4]



 3、深拷贝(Deep Copy)

深拷贝创建一个新对象,对于对象中的元素,深拷贝都会重新生成一份,而不是简单的使用原始元素的引用。

# e = copy.deepcopy(a) 新建了一个新对象,完整的在内存中复制原有对象
>>> e = copy.deepcopy(a)  
>>> print(e)
[[1, 2], 3, 4]

>>> id(a)  # e 和 a 的地址不一样
4408148552
>>> id(e)
4408394792

>>> id(a[0])  # e[0] 和 a[0] 的地址不一样
4408022944
>>> id(e[0])
4408398432

>>> e[0][0] = 5
>>> print(e)  # 由于e[0] 和 a[0] 的地址不一样,则改变 e[0] 的值不会改变 a[0] 的值
[[5, 2], 3, 4]
>>> print(a)
[[1, 2], 3, 4]

Note

关于浅拷贝和深拷贝的区别,Python 的 document是这样解释的:

The difference between shallow and deep copying is only relevant for compound objects (复合对象)(objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
  • A deep copy constructs a new compound object and then, recursively(递归地), inserts copies into it of the objects found in the original.
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,拷贝指的是创建一个新的对象,包含原始对象的所有内容。但是,深拷贝浅拷贝会根据拷贝方式的不同,影响拷贝结果。 深拷贝Deep Copy)是指创建一个新的对象,包含原始对象的所有内容,甚至包括原始对象中引用的对象。也就是说,深拷贝会递归地复制所有对象,包括它们的内部对象。深拷贝的结果是两个完全独立的对象,修改一个对象不会影响另一个对象。 浅拷贝Shallow Copy)是指创建一个新的对象,包含原始对象的所有内容,但不会递归复制原始对象中引用的对象。也就是说,浅拷贝复制对象的顶层内容,而不会对其内部对象进行复制浅拷贝的结果是两个对象共享同一个内部对象,修改一个对象会影响另一个对象。 下面是一个例子,可以更好地说明深拷贝浅拷贝的区别: ```python import copy # 定义一个列表 a = [1, 2, [3, 4]] # 浅拷贝 b = copy.copy(a) # 深拷贝 c = copy.deepcopy(a) # 修改a的第二个元素 a[1] = 5 # 修改a的第三个元素中的第一个元素 a[2][0] = 6 # 输出a、b、c的值 print(a) # [1, 5, [6, 4]] print(b) # [1, 2, [6, 4]] print(c) # [1, 2, [3, 4]] ``` 在上面的例子中,我们先定义了一个列表a,它包含了一个嵌套列表。我们使用copy.copy()和copy.deepcopy()对a进行拷贝,并修改原始列表a的值。最后,我们输出了三个列表的值,可以看到,浅拷贝b的第三个元素的值也被修改了,而深拷贝c的值没有受到影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值