在python里有深浅拷贝之说,何为浅拷贝?
看代码:
>>> a = [11,22,33]
>>> b = a
>>> id(a)
25084152
>>> id(b)
25084152
>>> b.append(44)
>>> a
[11, 22, 33, 44]
>>> b
[11, 22, 33, 44]
这便是最简单的浅拷贝,可以发现a、b地址相同,指向同一片内存(拷贝的是引用),同时改变b的值之后a也随之改变。
再看深拷贝:
>>> import copy
>>> a = [11,22,33]
>>> c = copy.deepcopy(a)
>>> id(a)
25085632
>>> id(c)
25274928
>>> a.append(44)
>>> a
[11, 22, 33, 44]
>>> c
[11, 22, 33]
可以看出c是对a的深拷贝,但是c和a的地址并不相同,意思是深拷贝将会开辟新的内存空间,同时将拷贝对象的数值拷贝进去(只拷贝数值),但是c并不指向a的地址。改变a的值也并不会令c的值改变。
但是可能会出现下面这种情况:
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [a,b]
>>> d = copy.deepcopy(c)
>>> a.append(4)
>>> c[0]
[1, 2, 3, 4]
>>> d[0]
[1, 2, 3]
可以看出c这个列表里有a和b的引用,那么深拷贝给d之后,d对a和b是拷贝引用还是数值呢。可以发现改变了a之后,d中的a并没有改变,可见 d中的a 与 c中的a 并不指向同一块内存空间。类似于函数的递归调用,深拷贝会将一层一层的引用的值给拷贝出来,且为其开辟新的内存空间。
同时值得一提的便是copy.copy()方法与copy.deepcopy()方法有一定的区别,如下代码:
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> c = [a,b]
>>> d = copy.copy(c)
>>> id(c)
25255688
>>> id(d)
25255168
>>> a.append(4)
>>> c[0]
[1, 2, 3, 4]
>>> d[0]
[1, 2, 3, 4]
可以发现copy()方法仅仅拷贝了c的数值,但对a和b依然是拷贝引用。更有对元组的特殊情况,如下代码:
>>> a = (1,2,3)
>>> b = copy.copy(a)
>>> id(a)
28644656
>>> id(b)
28644656
可以发现此处的copy()方法采用的是浅拷贝。
总结如下:
使用copy模块的copy功能的时候,它会根据当前拷贝的数据类型是可变类型还是不可变类型,有不同的处理方式。