在python中,对象的赋值往往是通过“=”进行的。但是由于“=”右边的类型方式不一样,所以产生变量虽然值相同,但是在内存中的地址值不同,可能会造成内存空间的浪费。如题所示,对象赋值中存在三种类型情况的赋值
引用赋值l2=l1 ,首先创建个变量l2,然后在创建一条引用,把这条引用指向l1的地址值。然后l1和l2共同使用这一块地址值。
当l1进行变化后,l2也跟着变化
l1= ['hello'] l2= l1 print(id(l1),id(l2) ) #1580262888480 1580262888480 print(l1,l2) # ['hello'] , ['hello'] print(l1 is l2) # true l1.append("word") print(l1,l2) ['hello', 'word'] ['hello', 'word'] print(id(l1),id(l2) ) print(l1 is l2) #true关于赋值拷贝,浅拷贝,深拷贝的具体适用场景:
当我们仅仅想适用某个对象的值的时候,我们就应该适用深拷贝,来切断他与原拷贝对象的关系,以免随着拷贝对象的变化而变化,但是从内存方面,又多占用内存空间;
当我们想加深连个对象之间的联系,就应使用“引用”
对于非容器类型(如数字、字符串、和其他'原子'类型的对象)没有被拷贝一说,因为他们每次创建都是同一个地址值。
如果元祖变量只包含原子类型对象,则不能深拷贝。
ll=[0,1,2,3,4,5,6,7,8,9] #为这个列表增加一组可变的子元素 ll.append([888888,99999]) import copy from copy import deepcopy ''' 引用赋值,浅copy, 深copy ''' #分别产生对象的数据 l3=ll #赋值 l2=ll.copy() #浅拷贝 l4=deepcopy(ll) #深copy #操作:对于不可变的子元素操作 ll.append('10') l2.append('12') l3.append('13') #由于引用赋值时,它还是在原对象上面修改的。所以会追加2次操作 l4.append('14') print(ll,l2,l3) print("浅copy的对象是个列表,对于不可变的对象,修改原不可变对象是不受影响的") #操作:对于可变的子元素操作 ll[-3][0]=0 print(ll,l2,l4) #浅copy和赋值都会改变,深copy不会改变。 print("浅copy的对象是个列表,对于其内部的可变对象,如当前元素是列表下的一个子列表," " 修改它时会随着被copy对象的变化而变化") ''' 所以综上所述:当改变原对象后,想不影响copy后的元素使用, 第一种方式:使用浅copy时,并且确保里面的元素全部为不可变对象。 第二种方式:使用deepcopy,但是增加了内存开销。 '''
