python中的拷贝是针对嵌套的可变数据类型的;
可变数据类型:列表、字典、集合;
不可变数据类型:数字、字符串、元组
举例(来源python核心编程):
import copy
person = [‘name’, [‘saving’, 100.00 ]]
hubby = person[:] -------person的一个浅拷贝:创建了一个新对象,地址是新的,内容是person中的内容;嵌套的可变数据类型中的地址是原来的,内容是原来的;
wifey = list(person) -------person的一个浅拷贝
son = copy.copy() -------person的一个浅拷贝
daug = copy.deepcopy() -----person的一个深拷贝:创建了一个新对象,地址是新的,内容是person中内容;嵌套的可变数据类型(列表)的地址也是新的,值是原来的值;
查看原person,hubby,wifey,son,daug的地址:
for i in person, hubby, wifey, son, daug:
print(id(i), end=’ ‘)
2749349998472 2749350110408 2749348557448 2749350110344 2749350110280 --------都不同
查看原person,hubby,wifey,son,daug的值:
for ii in person, hubby, wifey, son, daug:
print(ii, end=’ ')
[‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 100.0]] ---------都相同
查看原person,hubby,wifey,son,daug中每个元素的地址:
for j in person:
print(id(j), end=’,’)
#其他同上
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749350110216,--------深拷贝嵌套列表地址为新地址
修改深拷贝对象daug[1][1] = 30.00后,查看person,hubby,wifey,son,daug的地址:
2749349998472 2749350110408 2749348557448 2749350110344 2749350110280 -----不变
查看上述的值:
[‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 100.0]] [‘name’, [‘saving’, 30.0]] -----只有深拷贝的值改变,其他不变
查看person,hubby,wifey,son,daug中每个元素的地址:
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749350110216, —不变
修改浅拷贝对象hubby[1][1] = 50.00后,查看person,hubby,wifey,son,daug的地址:
2749349998472 2749350110408 2749348557448 2749350110344 2749350110280 ----不变
查看上述的值:
[‘name’, [‘saving’, 50.0]] [‘name’, [‘saving’, 50.0]] [‘name’, [‘saving’, 50.0]] [‘name’, [‘saving’, 50.0]] [‘name’, [‘saving’, 30.0]] -----浅拷贝对象的值都改变了,原因如前所述,浅拷贝只拷贝了内部列表的引用(地址);当引用的内容修改,所有浅拷贝对象的值也被修改;
查看person,hubby,wifey,son,daug中每个元素的地址:
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749350110216, ----不变
举例:实际中哪些时候会用到浅拷贝、深拷贝?
例如想要得到一幅图像修改了某些像素值后的图像,又需要保留原图;
此时就需要使用原图的深拷贝,修改深拷贝相应的值后得到 新图,不会影响到原图的使用;
简陋的实验代码:
import copy
person = ['name', ['saving', 100.00]]
hubby = person[:] # 新地址,老值
wifey = list(person) # 新地址,老值
son = copy.copy(person) # 新地址,老值
daug = copy.deepcopy(person) # 新地址,老值
def calc(x,y,z,a,b):
for i in person, hubby, wifey, son, daug:
print(id(i), end=' ')
print(end='\n')
for ii in person, hubby, wifey, son, daug:
print(ii, end=' ')
print(end='\n')
for j in person:
print(id(j), end=',')
print(end='\n')
for j in hubby:
print(id(j), end=',')
print(end='\n')
for j in wifey:
print(id(j), end=',')
print(end='\n')
for j in son:
print(id(j), end=',')
print(end='\n')
for j in daug:
print(id(j), end=',')
print(end='\n')
calc(person,hubby,wifey,son,daug)
daug[1][1] = 30.00
calc(person,hubby,wifey,son,daug)
hubby[1][1] = 50.00
calc(person,hubby,wifey,son,daug)
输出结果:
2749349998472 2749350110408 2749348557448 2749350110344 2749350110280
['name', ['saving', 100.0]] ['name', ['saving', 100.0]] ['name', ['saving', 100.0]] ['name', ['saving', 100.0]] ['name', ['saving', 100.0]]
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749350110216,
2749349998472 2749350110408 2749348557448 2749350110344 2749350110280
['name', ['saving', 100.0]] ['name', ['saving', 100.0]] ['name', ['saving', 100.0]] ['name', ['saving', 100.0]] ['name', ['saving', 30.0]]
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749350110216,
2749349998472 2749350110408 2749348557448 2749350110344 2749350110280
['name', ['saving', 50.0]] ['name', ['saving', 50.0]] ['name', ['saving', 50.0]] ['name', ['saving', 50.0]] ['name', ['saving', 30.0]]
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749349998280,
2749342608272,2749350110216,
Process finished with exit code 0