现在的位置: 主页 > 公司荣誉 > 文章列表

Python对象拷贝——深拷贝与浅拷贝

作者:成都金海力科技有限公司 来源:www.scjinhaili.com 未知发布时间:2017-09-13 13:20:21
Python对象拷贝——深拷贝与浅拷贝

对象的赋值实际上是对对象的引用。也就是说当把一个对象赋值给另一个对象时,只是拷贝了引用。如:

>>> t1 = tuple('furzoom') >>> t2 = t1 >>> id(t1),id(t2) (139792198303936, 139792198303936)

上面t1和t2代表的是同一个对象。

2. 浅拷贝

除了上面将一个对象直接赋值给另一个对象外,还有两种常用的方法对对象进行拷贝:使用切片操作和工厂方法。

>>> car = ['grand', ['length', 4.85]] >>> a4 = car[:] >>> a6 = list(car) >>> [hex(id(x)) for x in car, a4, a6] ['0x7f23e84da2d8', '0x7f23e84da128', '0x7f23e84da3f8']

通过创建汽车a4和a6,确实表示是不同的对象。现在继续完善a4和a6,修改它们的名字,和汽车长度。

>>> a4[0] = 'a4' >>> a6[0] = 'a6' >>> a4, a6 (['a4', ['length', 4.85]], ['a6', ['length', 4.85]]) >>> a4[1][1] = 4.761 >>> a4, a6 (['a4', ['length', 4.761]], ['a6', ['length', 4.761]])

修改汽车名字时,他们表现是正常的,而修改汽车车长时,发生了不期望的结果,修改a4的长度,同时也影响了a6的长度。

为什么会这样呢?原因在于只是针对序列做了浅拷贝。序列类型对象的浅拷贝是默认的拷贝,体现在:使用切片操作[:]、工厂函数、copy模块的copy函数。当改变a6汽车名字时,为什么没有体现在a4汽车上呢?这是因为名字是字符串类型,它是一个不可变类型,改变其内容将引用新建的对象。如下:

>>> a8 = list(car) >>> [hex(id(x)) for x in car] ['0x7f23e84d7a80', '0x7f23e84da320'] >>> [hex(id(x)) for x in a8] ['0x7f23e84d7a80', '0x7f23e84da320'] >>> [hex(id(x)) for x in a4] ['0x7f23e84d4d78', '0x7f23e84da320'] >>> [hex(id(x)) for x in a6] ['0x7f23e84d4e40', '0x7f23e84da320']

在a4和a6的第二项,它们引用的是同一个对象。

3. 深拷贝

要想避免上面的这种影响,需要对列表进行深拷贝。需要使用copy模块的deepcopy()函数。

如:

>>> car = ['grand', ['length', 4.85]] >>> a4 = car >>> import copy >>> a6 = copy.deepcopy(car) >>> [hex(id(x)) for x in car, a4, a6] ['0x7f23e84da098', '0x7f23e84da098', '0x7f23e84da440'] >>> a4[0] = 'a4' >>> a6[0] = 'a6' >>> a4,a6 (['a4', ['length', 4.85]], ['a6', ['length', 4.85]]) >>> a4[1][1] = 4.761 >>> a4,a6 (['a4', ['length', 4.761]], ['a6', ['length', 4.85]])

另,在copy模块中,只有两个函数,copy和deepcopy。

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:咸宁SEO http://xianning.4567w.com

上一篇:网站服务管理系统wdcp系列教程之(七) 下一篇:最后一页