拷贝python对象之浅拷贝和深拷贝

1.对象赋值

 在了解浅拷贝和深拷贝之前,我们必须搞清楚一个概念:对象的赋值实际上只是简单的对象引用,也就是说,当你创建一个对象,然后把它赋给一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。它们指向的仍然是同一块地址,可以把它理解为c语言中的指针.

>>> a=[1,2,3,4]
>>> id(a)
139867365855600
>>> b=a
>>> [id(x) for  x in a,b]
[139867365855600, 139867365855600]
>>> 

从结果可以看出,把列表a赋给了变量b,可b的内存空间地址仍然是a的地址,也就是说,只是b单纯的指向了列表a。

2.浅拷贝

hubby通过切片操作拷贝person,wifey通过工厂方法拷贝person.

>>> person=['name',['saving',100]]
>>> hubby=person[:]
>>> wifey=list(person)
>>> wifey
['name', ['saving', 100]]
>>> hubby
['name', ['saving', 100]]
>>> 

 来看它们的id值并不相同,说明它们是不相同的对象.

>>> [id(x) for x in person,hubby,wifey]
[139867365828944, 139867365856464, 139867365856752]

为hubby和wifey重新命名:

hubby

>>> hubby[0]='hubby'
>>> wifey[0]='wifey'
>>> print hubby, wifey
['hubby', ['saving', 100]] ['wifey', ['saving', 100]]
>>> 

然后为改变它们的存款:

>>> hubby[1][1]=50
>>> print hubby, wifey
['hubby', ['saving', 50]] ['wifey', ['saving', 50]]

当我们改变hubby的值时,wifey的值也改变了,这是为什么呢,不是它们属于不同的对象吗,对,它们确实属于不同的对象,先来看看它们各自内部元素的id:

>>> [id(x) for x in hubby]
[139867365833104, 139867365855312]
>>> [id(x) for x in wifey]
[139867365833488, 139867365855312]
>>> 

有没有恍然大悟呢,大家可以发现,hubby和wifey的第二个元素指向同一个地址,这样修改了hubby ,当然wifey 的值也会改变,但是名字为什么之间互相不影响呢,大家都知道,字符串属于不可变类,当hubby和wifey 重新命名时,会重新开辟空间,用'hubby'和‘wifey’替换'name';

总结一下浅拷贝:对一个对象进行赋值其实是创建了一个类型和原对象,其内容是原来对象元素的引用.打个比方,就像你换了一件衣服,但其穿衣服的人没有变,其内容不变。

注意:序列类型的浅拷贝是默认类型的拷贝,有以下几种方式实施(1):完全切片[:],(2):利用工厂函数list(),dict()等,(3)使用copy模块的copy函数.

3.深拷贝

浅拷贝是只单纯的拷贝了新的对象,其内容不会被复制,那么深拷贝,显而易见就是从外在到本质都会复制。

深拷贝用copy模块的deepcopy()函数:

>>> person=['name',['saving',100]]
>>> import copy
>>> hubby=copy.deepcopy(person)
>>> wifey=copy.deepcopy(person)
>>> print hubby,wifey
['name', ['saving', 100]] ['name', ['saving', 100]]
>>> hubby[1][1]=50
>>> print hubby,wifey
['name', ['saving', 50]] ['name', ['saving', 100]]
>>> 

看结果:改变了hubby[1][1]的值,wifey[1][1] 的值并没有改变,说明它们的地址不同,看一下它们的id值:

>>> [id(x) for x in hubby]
[139867429551728, 139867365856104]
>>> [id(x) for x in wifey]
[139867429551728, 139867365855528]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值