免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: lin_style
打印 上一主题 下一主题

一个关于深,浅拷贝问题。我这样理解对吗? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-03-30 18:59 |只看该作者
不对

您还是没说清楚

hubby[0]='abc'
hubby = person[:]  
这两个等号赋值区别。

对于['name', ['savings', 100.00]]来说,
为什么前者是浅浅拷贝,后者是深浅拷贝?

论坛徽章:
0
12 [报告]
发表于 2009-03-30 19:01 |只看该作者
原帖由 zhenglxd 于 2009-3-30 17:18 发表

>>> import copy
>>> a=[1,2,[3,4]]
>>> b=a[:]
>>> c=copy.copy(a)
>>> d=copy.deepcopy(a)
>>> id(a)
20055504
>>> id(b)
20074624
>>> id(c)
20063456
>>> id(d)
20070528
>>> a[2][0]='a'
...



你输出这些ID没什么意义,这些只是表示变量本身的地址,不代表里面变量的值地址
至少也要
[id(x) for x in a]

论坛徽章:
0
13 [报告]
发表于 2009-03-30 19:08 |只看该作者

回复 #10 lin_style 的帖子

我以前也困惑过
我把我前面的回复总结下

copy.deepcopy是深copy
深copy 的意思就是所拷即所得,你copy对象是什么 那么新生成对象就是什么,他是个独立的对象,他的行为更像我们映像中的copy. 你不要想去其他的内部索引之类的,你所看到的是什么,deepcopy后就是什么,完全一样并且独立。

copy.copy()和 [:]都是浅copy
如果你的容器里 没有其他可变容器的情况下,那么他的行为和deepcopy一样,如果有其他可变容器比如说
>>> a=[1,2,3,{'a':'b'}]
>>> b=a[:]
>>> a[3]['a']='c'
>>> print a
[1, 2, 3, {'a': 'c'}]
>>> print b
[1, 2, 3, {'a': 'c'}]
上面的例子中 内部的容器跟着变了
在看下面的
>>> a[0]='a'
>>> print a
['a', 2, 3, {'a': 'c'}]
>>> print b
[1, 2, 3, {'a': 'c'}]
2者的区别是 一个是对 a进行修改,而b是个独立的copy 所以b没有变
但是 a[3]['a']='c' 修改的原始对象 所以修改被继承了


在看这个
>>> a=[1,2,3,[1,2,3]]
>>> b=a[:]
>>> a[3]=4
>>> print a
[1, 2, 3, 4]
>>> print b
[1, 2, 3, [1, 2, 3]]

他修改的是a[3] 所以b没跟着变

论坛徽章:
0
14 [报告]
发表于 2009-03-30 19:17 |只看该作者
原帖由 lin_style 于 2009-3-30 18:59 发表
不对

您还是没说清楚

hubby[0]='abc'
hubby = person[:]  
这两个等号赋值区别。

对于['name', ['savings', 100.00]]来说,
为什么前者是浅浅拷贝,后者是深浅拷贝?

没那么多复杂的东西

=是赋值符 ,仅仅是把某个对象赋值给一个变量,不是创建一个新的变量
a=b 和a=b[:]是2个概念

浅copy和深copy 都是创建了一个新的对象

a=b[:] 是浅copy, 只有copy.deepcopy才是深copy

再聚个例子
a=[1,2,3,[1,2,3]]
b=a[:]

上面的例子里 [1,2,3,[1,2,3]] 这个是对象本身 用ob[0]标记 表示没有引用
a=[1,2,3,[1,2,3]] 用ob[1]表示 a是对他的唯一引用
b=a[:] b是a的浅copy 如果a内部没有其他可变容器结构 那么 就等于深copy
所以如果 a[0],a[1]..之类基于a的成员被修改 不会改变b的成员

但是如果像a[3][0~n]被修改 则会改变b里相应的成员
应为 a[3][0~n] 修改的不是 a,他修改的是 ob[0]内部的

深copy则是 完全copy你看到什么就copy什么 不会发生变化

论坛徽章:
0
15 [报告]
发表于 2009-03-30 21:00 |只看该作者
原帖由 zhenglxd 于 2009-3-30 19:17 发表

没那么多复杂的东西

=是赋值符 ,仅仅是把某个对象赋值给一个变量,不是创建一个新的变量
a=b 和a=b[:]是2个概念

浅copy和深copy 都是创建了一个新的对象

a=b[:] 是浅copy, 只有copy.deepcopy才是深 ...



这句点化了我。谢谢。。大致明白了。不过我还是喜欢遵循传值和传指针的原则来看待。。虽然我知道应该从语言高处的抽象层来看,比如句柄就应该是个句柄的概念,套接字就是个套接字。
再次谢谢

论坛徽章:
0
16 [报告]
发表于 2009-04-08 16:24 |只看该作者
我想 python源码分析 那本书在这个问题上 应该有很清楚的解释吧
吾翻书去也
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP