深拷贝与浅拷贝
深拷贝与浅拷贝的理解
拷贝就是复制,复制就是变量赋值。变量分为简单变量和复合变量。对于简单变量,拷贝就是常规变量间赋值;对于复合变量,拷贝分为浅拷贝和深拷贝。也就是说,简单变量不分浅拷贝和深拷贝,它们拷贝的结果是一样的。
浅拷贝,产生一个新的复合变量(对象),复制了原复合变量的外层对象和子对象的引用(引用与子对象有关联)。
深拷贝,产生一个新的复合变量(对象),复制了原复合变量的外层和子对象的副本(副本与子对象无关联)。
Python标准库中提供了copy模块,里面copy.copy()和copy.deepcopy()分别用于变量(对象)的浅拷贝和深拷贝。
另外,Python中不可变对象的拷贝不会创建新对象,可变对象的拷贝会创建新对象。
简单对象int类型(并且不可变对象)的拷贝,不创建新对象
import copy
a = 12
b= a # 赋值拷贝
c = copy.copy(a) # 浅拷贝
d = copy.deepcopy(a) # 深拷贝
print(id(a)) # 140705177314032
print(id(b)) # 140705177314032
print(id(c)) # 140705177314032
print(id(d)) # 140705177314032
简单对象str类型(并且不可变对象)的拷贝,不创建新对象
import copy
a = "abc"
b= a # 赋值拷贝
c = copy.copy(a) # 浅拷贝
d = copy.deepcopy(a) # 深拷贝
print(id(a)) # 1888525808240
print(id(b)) # 1888525808240
print(id(c)) # 1888525808240
print(id(d)) # 1888525808240
简单对象list类型(可变对象)的拷贝,创建新对象
import copy
a = [12,"abc"]
b= a # 赋值拷贝
c = copy.copy(a) # 浅拷贝
d = copy.deepcopy(a) # 深拷贝
print(id(a)) # 1463420727432
print(id(b)) # 1463420727432 可变对象的对象地址赋值
print(id(c)) # 1463423010952 新对象
print(id(d)) # 1463423189384 新对象
复合对象的深拷贝与浅拷贝
示例中的复合对象是list嵌套对象。
import copy
a = [12,"abc",[1,2,3]]
b= a # 赋值拷贝
c = copy.copy(a) # 浅拷贝
d = copy.deepcopy(a) # 深拷贝
print(id(a)) # 1764972890120
print(id(b)) # 1764972890120 可变对象的对象地址赋值
print(id(c)) # 1764973061640 新对象
print(id(d)) # 1764972968136 新对象
print("----------------------------------------------")
print(a) # [12, 'abc', [1, 2, 3]] 复合对象
print(a[2]) # [1, 2, 3] 子对象
print(b) # [12, 'abc', [1, 2, 3]] 浅拷贝对象
print(c) # [12, 'abc', [1, 2, 3]] 浅拷贝对象
print(d) # [12, 'abc', [1, 2, 3]] 深拷贝对象
print(id(a[2])) # 1764970855560
print(id(b[2])) # 1764970855560
print(id(c[2])) # 1764970855560 浅拷贝中子对象与原复合对象地址相同,是引用
print(id(d[2])) # 1764973081928 深拷贝中子对象与原复合对象地址不同,是副本
更多相关内容可以参考标准库讲解。