用markdown写的第一篇技术博客,使用Python类复制时走过的坑,
1 问题描述
- 浅拷贝问题最简单的体现方式,将一个类a(list等)赋值给另一个变量b,则修改a,会同时改变b。
‘’’
》 a
[1, 2, 1]
》 b=a
》a
[1, 2, 1]
》 b
[1, 2, 1]
》 a.append(3)
》 a
[1, 2, 1, 3]
》 b
[1, 2, 1, 3]
》
‘’’ - 以如下方式复制扩展的列表,也存在浅拷贝问题,c中的三个list元素指向了同一个list原型,对其中一个元素进行扩展时 ,三个元素同时发生了变化。
‘’’
》c=[[]]*3
》 c
[[], [], []]
》 c[1].append(1)
》 c
[[1], [1], [1]]
》 ‘’’ - 下面这段代码更让人吃惊,将c[1]赋值给b,修改b时,c的元素也全部发生了变化。
‘’’
》 c=[[]]*3
》 c
[[], [], []]
》 b=c[1]
》 b
[]
》b.append(1)
》 b
[1]
》 c
[[1], [1], [1]]
‘’’ - 对c中的元素进行加减乘除的运算修改时,c中的其他元素也同时变化,基本可以表明用c = [[]]*3这种方式产生的c中的三个元素,本质上是同一个元素,
‘’’
》c[1][0]
1
》 c[1][0] += 1
》 c[1][0] += 1
》 c[1][0]
3
》 c
[[3], [3], [3]]
‘’’
2.浅拷贝的解决方案
- 解决上述浅拷贝问题,可利用copy模块的copy()和deepcopy()方法。 Import copy 或 from copy import deepcopy 经过测试(python3.4)主要特点如下:
1、list类进行copy时,两个变量相互独立,互不影响。
‘’’
》 a=[1,2,3]
》 b=a.copy()
》 b
[1, 2, 3]
》 b[2] =8
》 a
[1, 2, 3]
》 b
[1, 2, 8]
》 b.append(2)
》 b
[1, 2, 8, 2]
》 a
[1, 2, 3]
‘’’
2、dict类存在浅拷贝问题,替换新复制的字典里的值不会改变原字典,但修改一个值时,会影响到原字典。额。。这个很绕。因此需要特别注意对值进行替换(全部)和修改(部分)的差别。
3.使用deepcopy(var)可以完全的复制一个类,两个类不再有任何关联,从而解决浅拷贝问题。
4、对于自定义类,由于没有内建的copy()函数,需要采用deepcopy进行完全复制。要注意:copy属于python自带类(list,dict等)内建的方法,采用dict.copy()调用,而deepcopy属于导入的外部函数,采用参数的形式,deepcopy(var)对变量进行复制
3.总结
- 涉及到类的复制和赋值时,最好不好直接用class1 = class2的方式对类进行赋值,也不要采用[class]*number 的方式,对类进行拓展。直接采用deepcopy()方法,就能避免浅拷贝问题。
最后编辑时间为: Jan.14, 2018 at 21:16