Python中赋值、浅拷贝与深拷贝的区别

赋值,其实就是对象的引用,对新对象的如何修改都会影响到原始对象。

Python中有两种拷贝操作:浅拷贝和深拷贝。

  • copy.copy(x):返回x的浅拷贝。
  • copy.deepcopy(x):返回x的深拷贝。

那么都是拷贝,浅拷贝和深拷贝有什么不同吗?

浅拷贝与深拷贝的差异只与复合对象(对象中包含其他对象,比如列表或类实例)相关。

  • 浅拷贝构造新的复合对象,然后向其插入对原始对象中对象(即子对象)的引用。
  • 深拷贝构建一个新的复合对象,然后递归的将原始对象中的包含的对象副本插入。

上面的话是什么意思呢?

我们需要明确的概念是,在python中,一个对象包括对象的id、对象类型和对象值。浅拷贝就是创建一个具有相同类型及相同值,但是id不同的新对象。在复合对象的拷贝时,若浅拷贝产生的新对象中有可变对象,则这些对象和原始对象中对应的值对应着同一个引用。就是浅拷贝只会拷贝父对象,不会拷贝子对象,所以改变新对象中的值时也会使原始对象中的值发生变化。

而深拷贝会递归的查找原始对象中包含的对象,并将其拷贝插入新的对象中,也就是父对象和子对象都会拷贝。因此,当我们改变新对象中的值时不会对原始对象产生影响,因为他们包含的对象都只是一个拷贝,不是引用。

我们还是借助一个例子直观的说明一下。

import copy

a=[1,2,3,4,['a','b']]
b=a             #赋值
c=copy.copy(a)   #浅拷贝
d=copy.deepcopy(a)   #深拷贝
a.append(5)   #修改对象a
a[4].append('c')  #修改对象a中的['a','b']这一数组对象
print(a)   # [1,2,3,4,['a','b'],5]
print(b)   # [1,2,3,4,['a','b'],5]
print(c)   # [1,2,3,4,['a','b','c']]
print(d)   # [1,2,3,4,['a','b']]

我们可以看到,a对象中包含了[‘a’,‘b’]这一数组对象。b是a赋值而来,这两都是指向同一个对象,所以对a的任何修改也体现在了b中。

c为对象a浅拷贝而来,其中1,2,3,4都是对a对象中相应数值的拷贝,而数组对象[‘a’,‘b’]则是对a中数组的引用,指向的是同一个东西。所以我们看到增加一个元素5时c对象没有变化,而对数组对象修改时c对象也发生变化。

d为对象a深拷贝得到,它递归的对a对象中的对象进行拷贝,即数组对象[‘a’,‘b’]也是一个拷贝,所以不论对a做什么样额修改,都不会影响到d对象。

猜你喜欢

转载自blog.csdn.net/dxk_093812/article/details/83691702