pythoncopy和deepcopy_Python中的Copy和Deepcopy

一,Python的对象:

Python存在大量的对象,我们一般提到的对象都是C中的结构体在堆中申请的一块内存(以CPython为例),每一个对象都有ID,可以通过ID(Object)获得。对象的范围包括内建类型的对象(如int类型的对象123,str的对象"test",list的对象[],生成器对象等等)、用户自建类型的对象、函数(lambda函数,生成器函数)、类型、Ture、False(bool类型的对象)、None(NoneType的对象)。

1 print id(123)2 print id("test")3 printid([])4 print id(xrange(1, 3))5 print id(lambdav: v)6 printid(int)7 printid(True)8 printid(None)9

10 print type(123)11 print type("test")12 printtype([])13 print type(xrange(1, 3))14 print type(lambdav: v)15 printtype(int)16 printtype(True)17 print type(None)

1 19257680

2 19062656

3 27888896

4 19590176

5 27863344

6 505361888

7 505379788

8 505354444

9

10

11

12

13

14

15

16

猜想int类型、True和None都是在高地址中,而动态生成的都是位于低地址中。

二,Python的引用计数:

所有对象都采用引用计数,给对象分配新名词或者将其放入容器中,这个对象的引用计数都会增加。当离开作用域或者被重新赋值的时候,这个对象的引用计数就会减少。当减少为0,垃圾收集器会将其销毁。

Python中的对象分为immutable和mutabel,作为immutable的int、char和tuple,相同的值在内存中只会生成一次,每次将其赋值到变量中,便会增加一个引用计数。而作为mutable的list、dict、xrange(生成器)和lambda(函数),每次生成都会在内存中生成一个新的对象。

另外:传参的时候,若参数为mutable,则传的是引用,若参数为immutable,则传的是值。

1 a = 123 #创建一个值为123的对象

2 b = 123 #增加123的引用计数

3 a = 111 #创建一个值为111的对象,减少123的引用计数

4 b = a #增加111的引用计数

5

6 c = [] #创建一个空队列

7 d = [] #创建一个新的空队列

8 c = [] #再创建一个新的空队列,减少原队列的引用计数

9 c = d #增加d队列的引用计数,减少c队列的引用计数

10 c.append(1) #创建一个值为1的对象,不改变原队列的引用计数

三,Shallow copy和Deep copy的区别

Python document中是这么说的:

A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

这其中的区别就是浅复制会简单的复制引用,不管他是mutable还是immutable。而深复制则会递归地复制immutable对象引用,对于mutable,则会新建一个对象。

1 importcopy2 a = [1, 2]3 b = [a, 3]4 c = copy.copy(b) #c = [[1, 2], 3]

5 d = copy.deepcopy(b) #d = [[1, 2], 3]

6 a.append(3) #c = [[1, 2, 3], 3]

7 #d = [[1, 2], 3]

四,如何控制Shallow copy和Deep copy?

在deepcopy时候,会遇到问题,比如有对象中有一个指向用户信息的列表,用户希望在复制的时候直接引用原列表。这个时候可以使用定制功能。

可以在类型中定义__copy__和__deepcopy__实现shallow copy和deep copy,当用户下次调用copy.copy和copy.deepcopy时,便会调用__copy__和__deepcopy__。

1 importcopy2 classExample(dict):3 def __init__(self, needcopy={}, userinfo={}):4 super(Example, self).__init__()5 self.need =needcopy6 self.user =userinfo7

8 def __deepcopy__(self, memo):9 if memo isNone:10 memo ={}11 result = self.__class__()12 memo[id(self)] =result13 for key inself.need.keys():14 result.need =copy.deepcopy(self.need)15 result.user =self.user16 returnresult17

18 needcopy = {"price": 100}19 userinfo = {"user": "vincent"}20 a =Example(needcopy, userinfo)21 b =copy.deepcopy(a)22 needcopy["title"] = "no"

23 userinfo["passwd"] = "none"

24 print "need:", a.need, "; user:", a.user25 print "need:", b.need, "; user:", b.user

1 need: {'price': 100, 'title': 'no'} ; user: {'passwd': 'none', 'user': 'vincent'}2 need: {'price': 100} ; user: {'passwd': 'none', 'user': 'vincent'}

Output

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值