1、不可变对象三个的地址都相同
2、可变对象:=:地址相同,改变原来的值都会改变新值
deepcopy:地址不相同,改变原来的值都不会改变新值
copy:地址不相同,无复杂子对象:改变原来的值不会改变新值
有复杂子对象,修改“子对象”原来的值新值才会改变
只有deepcopy和简单型可变对象的浅拷贝copy和不会影响原来的值,其他都会影响
deppcopy深拷贝:新建一个对象,把原来对象的内存完全复制过来,改变复制后的对象,不会改动原来内存的内容。(两个对象在复制之后是完全独立的对象)
=等号赋值:相当于为原来的对象打一个新的标签,两个引用指向同一个对象,修改其中的一个,另一个也会产生变化
copy浅拷贝:两种情况,1. 浅拷贝的值是不可变对象(数值、字符、元组)时,和等于赋值一样,对象的id值和浅拷贝原来的值相同;2. 如果是可变对象(列表、字典等),a. 一个简单的没有嵌套的对象,复制前后的对象相互之间不会影响,b. 对象中有复杂子对象,如列表嵌套,如果改变原来的对象中复杂子对象的值,浅拷贝的值也会受影响,因为在浅拷贝时只复制了子对象的引用(只拷贝父对象)。
总结:
1对于简单的对象,例如不可变对象(数值,字符串,元组),用 shallow copy 和 deep copy 没区别
2复杂的对象, 如 list 中套着 list 的情况,shallow copy 中的 子list,并未从原 object 真的「独立」出来。也就是说,如果你改变原 object 的子 list 中的一个元素,新的就会一起变化
#1.使用copy()拷贝不可变对象,指向地址相同
val1 = 1000
val2 = copy.copy(val1)
print(id(val1),id(val2))#8551568 8551568
#2.使用copy()拷贝简单可变对象,地址不同,改变值不会改变
ls1 =[1,2,3,4]
ls2 = copy.copy(ls1)
ls1.append(5)
print(id(ls1),id(ls2))#1551568 1551566
print(ls1,ls2) #[1, 2, 3, 4, 5] [1, 2, 3, 4]
#3.使用copy和deepcopy拷贝复杂可变对象,地址不同,改变值“会”改变
origin = [1, 2, [3, 4]]
cop1 = copy.copy(origin)
cop2 = copy.deepcopy(origin)
print(id(cop1),id(cop2))#
origin[2][0] = "hey!" #修改数据源的值
print(cop1,cop2) #[1, 2, ['hey!', 4]] [1, 2, [3, 4]]
#如果你改变原 object 的子 list 中的一个元素,浅copy中的 子list,并未从原 object 真的「独立」出来