python学习笔记2:个人理解之赋值、深拷贝、浅拷贝

1.直接赋值:其实就是对象的引用,两者指向相同的内存空间

2.浅拷贝(copy):copy模块中的copy方法,拷贝父对象,不会拷贝对象内部的子对象

3.深拷贝(deepcopy):copy模块中的deepcopy方法,完全拷贝父对象

个人理解:

(1)python中的拷贝分为深拷贝和浅拷贝,若不特殊说明,一般指浅拷贝

(2)浅拷贝是将对象的顶层进行拷贝,拷贝了引用,并没有拷贝内容,原对象改变,新对象也跟着变,但是浅拷贝对于可变类型和不可变类型是不同的,对于可变类型只拷贝顶层,不可变类型依然是原来的对象。

对于这句话更通俗一点的解释是:浅拷贝是拷贝了原来对象的引用,需要重新开辟空间保存该对象的引用,而对于该对象里面的子对象,只是拷贝了子对象的引用,对于可变类型来讲,id不会发生变化,但里面的对象会跟着变化而改变;对于不可变类型来讲,内容和id是不会发生任何变化的。

(3)深拷贝是对一个对象的所有层次的拷贝,但是修改原来的值,对新的对象不受影响

下面根据一个实例进行解释: 

# conding=utf-8
_author_ = "stz"
_time_ = '2018/7/21,9:32'

import copy

list1=[1,2,['a','b'],('c','d')]
list2=list1
print(id(list1),id(list2))
print('===================================')
list3=copy.copy(list1)
print(id(list1),id(list1[0]),id(list1[1]),id(list1[2]),id(list1[3]))
print(id(list3),id(list3[0]),id(list3[1]),id(list3[2]),id(list3[3]))
print('===================================')
list4=copy.deepcopy(list1)
print(id(list1),id(list1[0]),id(list1[1]),id(list1[2]),id(list1[3]))
print(id(list4),id(list4[0]),id(list4[1]),id(list4[2]),id(list4[3]))
print('===================================')

list1.append(3)
tuple1=(10,10)
list1[2].append({100})
list1[3]=list1[3]+tuple1

dict1={}
dict1['1']=1111
list1[2].append(dict1)

print(list1)
print(list2)
print(list3)
print(list4)
print('===================================')
print(id(list1),id(list2))
print('===================================')
print(id(list1),id(list1[0]),id(list1[1]),id(list1[2]),id(list1[3]))
print(id(list3),id(list3[0]),id(list3[1]),id(list3[2]),id(list3[3]))
print('===================================')
print(id(list1),id(list1[0]),id(list1[1]),id(list1[2]),id(list1[3]))
print(id(list4),id(list4[0]),id(list4[1]),id(list4[2]),id(list4[3]))

结果显示为:

D:\python3\python.exe E:/untitled/test3.py
41808968 41808968
===================================
41808968 502948064 502948096 41808776 40428552
41810248 502948064 502948096 41808776 40428552
===================================
41808968 502948064 502948096 41808776 40428552
41810184 502948064 502948096 41810120 40428552
===================================
[1, 2, ['a', 'b', {100}, {'1': 1111}], ('c', 'd', 10, 10), 3]
[1, 2, ['a', 'b', {100}, {'1': 1111}], ('c', 'd', 10, 10), 3]
[1, 2, ['a', 'b', {100}, {'1': 1111}], ('c', 'd')]
[1, 2, ['a', 'b'], ('c', 'd')]
===================================
41808968 41808968
===================================
41808968 502948064 502948096 41808776 40478584
41810248 502948064 502948096 41808776 40428552
===================================
41808968 502948064 502948096 41808776 40478584
41810184 502948064 502948096 41810120 40428552

Process finished with exit code 0

好的,我们对于每一步进行说明:

(1)list2=list1

list1直接赋值给list2,两者指向相同的内存空间,所以如果:

print(id(list1),id(list2))

结果是:

41808968 41808968,是一样的。所以无论你对list1,还是list2进行任何操作,两者都是指向相同的内存空间,其结果都是一样的。

(2)list3=copy.copy(list1)

list3浅拷贝list1,但是只是对于顶层元素的拷贝,只是拷贝对象的引用。

list3会重新开辟空间,保存list1中子对象的引用,指向的还是原来的地址。

当我们对list1进行append(3)操作时,我们发现,list3并没有添加。而对于可变类型list[2]进行append('{100}')和append(dict1),其指向的id并没有发生改变,而对于不可变类型,对list[3]进行+tuple1操作时,list[3]+tuple1会产生新的对象,所以在list1中id(list[3])发生了变化,而list3[3]并没有发生变化,还是指向原来的内存地址。

(3)list4=copy.deepcopy(list1)

list4深拷贝list1,是对list1中所有层次进行拷贝,包括子对象。相当于另外开辟了一个空间,保存list1的所有对象的引用。所以无论是可变类型,还是不可变类型,进行任何操作,对于深拷贝产生的新对象,它的指向,永远是原来对象的引用。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值