谈谈Python中对象拷贝

谈谈Python中对象拷贝

2013-10-17 18:44:52   来源:   
你想复制一个对象?因为在Python中,无论你把对象做为参数传递,做为函数返回值,都是引用传递的。何谓引用传递,我们来看一个C++交换两个

你想复制一个对象?因为在Python中,无论你把对象做为参数传递,做为函数返回值,都是引用传递的。

何谓引用传递,我们来看一个C++交换两个数的函数:

1
2
3
4
5
6
7
void swap( int  &a,  int  &b)
{
     int  temp;
     temp  =  a;
     =  b;
     =  temp;
}

这个例子就是一个引用传递的例子!目的是说明一下概念:引用传递的意思就是说你传递的是对象的引用,对这个引用的修改也会导致原有对象的改变。学过C/C++的朋友们都知道,在交换2个数的时候,如果自己实现一个swap函数,需要传递其引用或者指针。

Python直接使用引用传递,多方便啊,你还要吐槽什么?你又想过我不想改变原对象的情况吗?如果有,那么看这里!

假设我现在有一个list,叫做l1,我现在需要一份l1的拷贝,如果我直接使用诸如l2 = l1的方式,然后我对l2进行一系列的修改,会等价于我对l1直接做修改,这可不是我想要的!如:

1
2
3
4
5
6
l1  =  [ 1 2 ]
l2  =  l1
l2.append( 3 )
print  l1
print  l2
# l1 = [1, 2, 3], l2 = [1, 2, 3]

这就是Python引用传递造成的,也就是说l1和l2属于同一list对象,那么如何才能得到一份不同的对象呢?这不是so easy嘛,用切片撒,比如:

1
2
3
4
l1  =  [ 1 2 ]
l2  =  l1[:]
l2.append( 3 )
# l1 = [1, 2], l2 = [1, 2, 3]

是的,目的达到了,别介,你确定这样一定行?让我们看看一个更复杂的情况:

1
2
3
4
5
6
l1  =  [[ 1 2 ],  3 ]
l2  =  l1[:]
l2.append( 4 )
# l1 = [[1, 2], 3], l2 = [[1, 2], 3, 4]
l2[ 0 ].append( 5 )
# l1 = [[1, 2, 5], 3], l2 = [[1, 2, 5], 3, 4]

啊哈,貌似出问题了哈,这个可不是我们需要的!怎么办呢?好了,进入今天的正题,Python中的copy模块!

import copy

如果你希望复制一个容器对象,以及它里面的所有元素(包含元素的子元素),使用copy.deepcopy,这个方法会消耗一些时间和空间,不过,如果你需要完全复制,这是唯一的方法。上面我们提到的切片的方式,等价于copy模块中的copy函数。

上面拷贝的操作变得so easy了:

1
2
3
4
5
6
7
l1  =  [[ 1 2 ],  3 ]
l2  =  copy.copy(l1)
l3  =  copy.deepcopy(l1)
l2.append( 4 )
l2[ 0 ].append( 5 )
l3[ 0 ].append( 6 )
# l1 = [[1, 2, 5], 3], l2 = [[1, 2, 5], 3, 4], l3 = [[1, 2, 6], 3]

相关说明:

copy(x)

   Shallow copy operation on arbitrary Python objects.

   See the module's __doc__ string for more info.

deepcopy(x, memo=None, _nil=[])

   Deep copy operation on arbitrary Python objects.

   See the module's __doc__ string for more info.


如对本文内容有疑问,或想进一步交流学习,欢迎通过以下方式:
1.  Python论坛
2. pythontab技术互助群 群① 群② 群满,剩余名额有限,需要验证加群,但是高手众多。验证码获取地址: 群验证码 
群③:318130924 开放加群 
3. 关注PythonTab微信,获取精彩资讯教程,公众号:Pythontab中文网 
版权声明:本站文章除非注明,均为原创内容,如需转载请务必注明出处,违者本站保留追究其法律责任之权利。
转自:http://www.pythontab.com/html/2013/pythonjichu_1017/589.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值