Python —— 深拷贝和浅拷贝

1、浅拷贝

浅拷贝就是对一个对象父级(外层)的拷贝,并不会拷贝子级(内部)。简单举个例子:

import copy

a = [1, 2, 3]
b = [3, 4, 5]
c = [a, b]
d = copy.copy(c)

上面代码中,c是对象父级,a和b是对象子级。当使用浅拷贝copy.copy()时,只会对c进行拷贝,不会对a和b进行拷贝。

具体可以进行验证:

import copy

a = [1, 2, 3]
b = [3, 4, 5]
c = [a, b]
d = copy.copy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

通过上面的代码可以发现,c和d的内存地址是不一样的,而子级的内存地址是一样的。

因此可以简单理解,当一个对象有对象父级和对象子级时,浅拷贝只会对对象父级进行拷贝而不会对对象子级进行拷贝。

但是当对象不分父级和子级的时候,浅拷贝就是简单的对对象进行拷贝:

import copy

a = [1, 2, 3]
b = copy.copy(a)

print(id(a))
print(id(b))

这种情况下a和b的内存地址是不一样的。

还需要注意的一种情况是,当对象父级的数据类型为不可变类型,比如是元组时,浅拷贝对象的时候还是引用原对象的地址。

import copy

a = [1, 2, 3]
b = [3, 4, 5]
c = (a, b)
d = copy.copy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

在上面这种情况下,对象父级是一个不可变数据类型,元组。因此在使用浅拷贝的时候,是对原对象的直接引用。因为父级对象是不可变类型,因此如果要修改父级的数据,会重新开辟新的内存空间进行存放,因此浅拷贝引用原对象的地址是没有问题的。

2、深拷贝

深拷贝是对一个对象的所有层次的拷贝,内部和外部都会被拷贝。

简单举个例子:

import copy

a = [1, 2, 3]
b = [2, 3, 4]
c = [a, b]
d = copy.deepcopy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

代码中copy.deepcopy()是对原对象进行深拷贝,这种情况下,对象父级被拷贝,对象子级也会被拷贝,对象之间的内存地址完全不同。

但是深拷贝中需要注意,当对象父级是一个不可变类型,对象子级是一个不可变类型,当使用深拷贝的时候,新对象是对原对象的引用。

import copy

a = (1, 2, 3)
b = (2, 3, 4)
c = (a, b)
d = copy.deepcopy(c)

print(id(c))
print(id(d))
print(id(c[0]))
print(id(d[0]))

代码中的对象父级和子级都是不可变类型,元组。这种情况下,深拷贝得到的新对象是对原对象的引用,两者对应的内存地址是一样的。

深拷贝的作用是在做数据清洗或者数据修改等操作前,对原始数据复制一份,以防数据修改,找不到原数据。

当对象父级和对象子级是不可变类型时,是不能在原始对象上对数据进行修改的,这时候深拷贝对对象的拷贝是引用就可以理解了。因为我是不可变数据,所以怎么对数据进行清洗也不会改变原始数据,所以直接对原对象进行引用就可以了。

你可能感兴趣的:(python编程高手之路)