天天看点

Python深浅拷贝的区别一、可变对象与不可变对象二、深浅拷贝注意点:可变元素的拷贝三、eg:

一、可变对象与不可变对象

可变对象:一个对象在不改变其所指向的地址的前提下,可已修改地址中的值

不可变对象:一个对象的地址是不能修改的,如果修改了这个对象的值,他所指向的地址也会改变

常见不可变元素包含:
int,float,complex,long,str,unicode,tuple
           

二、深浅拷贝注意点:可变元素的拷贝

深浅拷贝看上去都会生成一个相同的值,但是拷贝出来的地址不同。

浅拷贝时,拷贝出来的新对象的地址与原对象不同,但是新对象里面的可变元素的地址和原对象里的可变元素的地址时相同的。

深拷贝时,直接开辟新的地址存放新对象,无论如何修改新对象,都不会对原对象造成影响
           

三、eg:

import copy
a=[1,2,3,4,5,['a','b']]
#原始对象
b=a#赋值,传对象的引用
c=copy.copy(a)#对象拷贝,浅拷贝
d=copy.deepcopy(a)#对象拷贝,深拷贝
print("a=", a , "    id(a)=" ,id(a), "id(a[5])=" ,id(a[5]))
print("b=", b , "    id(b)=" ,id(b), "id(b[5])=" ,id(b[5])) 
print("c=",c,"    id(c)=",id(c),"id(c[5])=",id(c[5]))
print("d=",d,"    id(d)=",id(d),"id(d[5])=",id(d[5]))
print( "*"*70)

a.append(6)#修改对象a
a[5].append('c')#修改对象a中的['a','b']数组对象
print("a=",a,"    id(a)=",id(a),"id(a[5])=",id(a[5]))
print("b=",b,"    id(b)=",id(b),"id(b[5])=",id(b[5]))
print("c=",c,"       id(c)=",id(c),"id(c[5])=",id(c[5]))
print("d=",d,"            id(d)=",id(d),"id(d[5])=",id(d[5]))
           
Python深浅拷贝的区别一、可变对象与不可变对象二、深浅拷贝注意点:可变元素的拷贝三、eg:
从程序的结果来看,列表a和b是赋值操作,两个对象完全指向同一个地址,a和b就是同一块地址的两个引用,
其实就是一个东西,所以一个对象在修改浅层元素(不可变)或深层元素(可变)时,另一个对象也同时在变;

c是a进行浅拷贝生成的对象,可以看到a(或b)和c两个对象整体的id是不同的,但是里面的
第5个元素-列表的地址却是相同(指向同一个地址),
所以b在浅层次元素层面(不可变)增加一个元素时,c并没跟着增加,但是b的第5个元素-列表在增加一个元素时,
c的第5个元素也跟着增加了,这就是因为b和c的第5个元素-列表是指向同一个地址的,这个地址上的值变了,
在两个地方会同时改变;

再看d,d的浅层次元素(不可变)和 深层次元素(可变)的地址和a,b,c都不一样,所以,a,b,c无论怎么修改,
d都不会跟着改变,这就是深拷贝的结果。