In [1]: a = [11, 22, 33]
In [2]: b = a
In [3]: b
Out[3]: [11, 22, 33]
In [4]: id(a), id(b)
Out[4]: (2053851155016, 2053851155016)
In [5]: c = {"name": "hui"}
In [6]: d = c
In [7]: id(c), id(d)
Out[7]: (2053851035112, 2053851035112)
In [8]: a.append(44)
In [9]: a
Out[9]: [11, 22, 33, 44]
In [10]: b
Out[10]: [11, 22, 33, 44]
In [11]: c["age"] = 21
In [12]: c
Out[12]: {'name': 'hui', 'age': 21}
In [13]: d
Out[13]: {'name': 'hui', 'age': 21}
In [12]: a = [1, 2]
In [13]: b = [3, 4]
In [14]: c = [a, b]
In [15]: d = c
In [16]: id(c), id(d)
Out[16]: (1409068540040, 1409068540040)
In [17]: import copy
In [18]: e = c.copy()
In [19]: id(c), id(d), id(e)
Out[19]: (1409068540040, 1409068540040, 1409070776520)
# 浅拷贝copy的对象id()不一样
In [20]: id(c[0]), id(c[1])
Out[20]: (1409071493512, 1409071679112)
In [21]: id(e[0]), id(e[1])
Out[21]: (1409071493512, 1409071679112)
# 其子对象则一样
In [22]: a.append(5)
In [23]: b.append(6)
In [24]: c
Out[24]: [[1, 2, 5], [3, 4, 6]]
In [25]: d
Out[25]: [[1, 2, 5], [3, 4, 6]]
In [26]: e
Out[26]: [[1, 2, 5], [3, 4, 6]]
# 内容一致
In [28]: c.append(7)
In [29]: c
Out[29]: [[1, 2, 5], [3, 4, 6], 7]
In [30]: e
Out[30]: [[1, 2, 5], [3, 4, 6]]
可以看出直接赋值
c
和
d
是同一对象,而浅拷贝
copy
的
c
和
e
是一个分别独立的对象,但他们的子对象
a
,
b
还是
指向统一对象即引用
。
因此当
c.append(7)
后,只有
c
对象改变了,而浅拷贝的
e
还是没有变化。
当
a.append(5), b.append(6)
后,
c, d, e
对象依然内容一致。
深拷贝
通过
copy.deepcopy()
来实现深拷贝
In [33]: a = [1, 2]
In [34]: b = [3, 4]
In [35]: c = [a, b]
In [36]: d = copy.deepcopy(c)
In [37]: id(c), id(d)
Out[37]: (1409071919752, 1409071607112)
In [38]: id(c[0]), id(c[1])
Out[38]: (1409071948680, 1409071766216)
In [39]: id(d[0]), id(d[1])
Out[39]: (1409071976328, 1409071919880)
# 完全拷贝了,其子对象的id()都不一样
In [40]: c.append(5)
In [41]: c
Out[41]: [[1, 2], [3, 4], 5]
In [42]: d
Out[42]: [[1, 2], [3, 4]]
In [43]: a.append(3)
In [44]: b.append(5)
In [45]: c
Out[45]: [[1, 2, 3], [3, 4, 5], 5]
In [46]: d
Out[46]: [[1, 2], [3, 4]]
# 因此任c怎么修改,都影响不到d
In [47]: d[0].append(5)
In [48]: d[1].append(6)
In [49]: d
Out[49]: [[1, 2, 5], [3, 4, 6]]
In [50]: d.append(7)
In [51]: d
Out[51]: [[1, 2, 5], [3, 4, 6], 7]
In [52]: c
Out[52]: [[1, 2, 3], [3, 4, 5], 5]
# d怎么修改也影响不到c
深度拷贝, 完全拷贝了父对象及其子对象,两者是完全独立的。因此
c,d
做任何操作都互不影响。
三者对比
d = c
赋值引用,
c
和
d
都指向同一个对象
e = c.copy()
浅拷贝,
c
和
e
是一个
独立的对象
,但他们的
子对象还是指向统一对象即引用
。
f = copy.deepcopy(c)
深度拷贝,
c
和
f
完全拷贝了父对象及其子对象,两者是完全独立的
。
In [54]: # 可变类型list
In [55]: a = [1, 2, 3]
In [56]: b = copy.copy(a)
In [57]: id(a)
Out[57]: 1409069563528
In [58]: id(b)
Out[58]: 1409071719752
In [59]: a.append(4)
In [60]: a
Out[60]: [1, 2, 3, 4]
In [61]: b
Out[61]: [1, 2, 3]
In [63]: # 不可变类型 tuple
In [64]: c = (1, 2, 3)
In [65]: d = copy.copy(c)
In [66]: id(c)
Out[66]: 1409070834456
In [67]: id(d)
Out[67]: 1409070834456
当浅拷贝
copy()
不可变类型元组时
tuple
,
c, d
的内存地址都一样,说明仅是指向。
深拷贝测试
In [71]: a = ([1, 2], [3, 4])
In [72]: b = copy.copy(a)
In [73]: c = copy.deepcopy(a)
In [74]: id(a)
Out[74]: 1409068519944
In [75]: id(b)
Out[75]: 1409068519944
# 浅拷贝不可变类型id()一致
In [76]: id(c)
Out[76]: 1409071533448
# 深拷贝不可变类型id()不一致
In [77]: b[0].append(3)
In [78]: b[1].append(5)
In [79]: a
Out[79]: ([1, 2, 3], [3, 4, 5])
In [80]: b
Out[80]: ([1, 2, 3], [3, 4, 5])
In [81]: c
Out[81]: ([1, 2], [3, 4])
# 浅拷贝的子对象引用一致
In [82]: c[0].append(3)
In [83]: c
Out[83]: ([1, 2, 3], [3, 4])
In [84]: b
Out[84]: ([1, 2, 3], [3, 4, 5])