from copy import copy, deepcopy
a = {'0': [{'a':1}, 2, 3], '1': [4, 5, 6]}
b = a
c = copy(a)
d = deepcopy(a)
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))
print('------------------------------')
print('a 的list1地址:{}'.format(id(a['0'])))
print('b 的list1地址:{}'.format(id(b['0'])))
print('c 的list1地址:{}'.format(id(c['0'])))
print('d 的list1地址:{}'.format(id(d['0'])))
print('------------------------------')
print('a 的list1的dict1地址:{}'.format(id(a['0'][0])))
print('b 的list1的dict1地址:{}'.format(id(b['0'][0])))
print('c 的list1的dict1地址:{}'.format(id(c['0'][0])))
print('d 的list1的dict1地址:{}'.format(id(d['0'][0])))
print('------------------------------')
print('a 的第二层不可变对象地址:{}'.format(id(a['0'][1])))
print('b 的第二层不可变对象地址:{}'.format(id(b['0'][1])))
print('c 的第二层不可变对象地址:{}'.format(id(c['0'][1])))
print('d 的第二层不可变对象地址:{}'.format(id(d['0'][1])))
print('------------------------------')
print('a 的list1的dict1的值1地址:{}'.format(id(a['0'][0]['a'])))
print('b 的list1的dict1的值1地址:{}'.format(id(b['0'][0]['a'])))
print('c 的list1的dict1的值1地址:{}'.format(id(c['0'][0]['a'])))
print('d 的list1的dict1的值1地址:{}'.format(id(d['0'][0]['a'])))
运行结果:
a 的第一层对象地址:1973729844160
b 的第一层对象地址:1973729844160
c 的第一层对象地址:1973732897600
d 的第一层对象地址:1973732900288
------------------------------
a 的list1地址:1973732826176
b 的list1地址:1973732826176
c 的list1地址:1973732826176
d 的list1地址:1973732898816
------------------------------
a 的list1的dict1地址:1973729843968
b 的list1的dict1地址:1973729843968
c 的list1的dict1地址:1973729843968
d 的list1的dict1地址:1973733008064
------------------------------
a 的第二层不可变对象地址:1973728143696
b 的第二层不可变对象地址:1973728143696
c 的第二层不可变对象地址:1973728143696
d 的第二层不可变对象地址:1973728143696
------------------------------
a 的list1的dict1的值1地址:1973728143664
b 的list1的dict1的值1地址:1973728143664
c 的list1的dict1的值1地址:1973728143664
d 的list1的dict1的值1地址:1973728143664
字典 {'0': [{'a':1}, 2, 3], '1': [4, 5, 6]}
与各变量的存储关系如图所示:
- 变量存在栈里,对象存在堆里
- 第一层字典
{'0':[], '1':[]}
的对象如dict1所示,第二层的两个列表 如list1, list2所示,第三层的字典如dict2所示。各值如最后两列所示。 - 变量
a
指向dict1 赋值=
是新增了一个变量,但是不新建对象,该变量指向原对象。
故变量b
指向dict1
,id(a)=id(b)
:
a 的第一层对象地址:1973729844160
b 的第一层对象地址:1973729844160
copy
是新增了一个变量,只会新建第一层对象。
-故根据dict1
复制新建了新对象copy dict1
,变量c
指向copy dict1
,id(a)!=id(c)
:
a 的第一层对象地址:1973729844160
c 的第一层对象地址:1973732897600
dict1
和copy dict1
的内容完全一样,其中引用的第二层列表是不变的,故id(a['0'])=id(c['0'])
:
a 的list1地址:1973732826176
c 的list1地址:1973732826176
deepcopy
是把所有层都进行了复制新建。
根据dict2
复制新建得到了copy dict2
,list1
复制新建得到了copy list1
, dict2已经产生了新的,所以list1中的引用的地址变成了新的copy dict2
,以此类推。- 对于不可变对象的拷贝,是不会再产生新的对象。如下示例(更深层的机制待更新):
from copy import copy, deepcopy
a = 1
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))
a = 1000
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))
a = 'x'
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))
a = 'How are you?'
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))
a = (1,'x','haha lala')
b = a
c = copy(a)
d = deepcopy(a)
print('a={}'.format(a))
print('a 的第一层对象地址:{}'.format(id(a)))
print('b 的第一层对象地址:{}'.format(id(b)))
print('c 的第一层对象地址:{}'.format(id(c)))
print('d 的第一层对象地址:{}'.format(id(d)))
打印结果 :
a=1
a 的第一层对象地址:2697732450608
b 的第一层对象地址:2697732450608
c 的第一层对象地址:2697732450608
d 的第一层对象地址:2697732450608
a=1000
a 的第一层对象地址:2697737907088
b 的第一层对象地址:2697737907088
c 的第一层对象地址:2697737907088
d 的第一层对象地址:2697737907088
a=x
a 的第一层对象地址:2697732851056
b 的第一层对象地址:2697732851056
c 的第一层对象地址:2697732851056
d 的第一层对象地址:2697732851056
a=How are you?
a 的第一层对象地址:2697737822064
b 的第一层对象地址:2697737822064
c 的第一层对象地址:2697737822064
d 的第一层对象地址:2697737822064
a=(1, 'x', 'haha lala')
a 的第一层对象地址:2330191099200
b 的第一层对象地址:2330191099200
c 的第一层对象地址:2330191099200
d 的第一层对象地址:2330191099200