Python之探究类的复制和垃圾回收
一、引用计数和垃圾回收
先看一段代码:
In [32]: aOut[32]: [1, 2, 3, [45, 34]]In [33]: c = list(a)In [34]: d = copy.deepcopy(a)In [35]: bOut[35]: [1, 2, 3, [45, 34]]In [36]: cOut[36]: [1, 2, 3, [45, 34]]In [37]: a[3][0] = 'zhangsan'In [38]: aOut[38]: [1, 2, 3, ['zhangsan', 34]]In [39]: bOut[39]: [1, 2, 3, ['zhangsan', 34]]In [40]: cOut[40]: [1, 2, 3, ['zhangsan', 34]]In [41]: dOut[41]: [1, 2, 3, [45, 34]]到这里,我们能看出,当a改变,b,c也随之改变了,d依旧没变,那是不是说明只有d是成功的完成了复制,b和c都没有复制成功呢?这只对了一半,下面我们来一一说明。
第一句:b = a
可能用惯了C和Java对与复制这个概念,认为这么做就完成了复制。但是在python中这么做是不对的。我在python的书上看到这句话的解释是:“b是对a的引用”
对此,我有两种理解:
1、有一块内存地址存放着对象 [1,2,3] ,变量a作为这块内存的引用,存储了它的地址,变量b作为a的引用存储了a的地址
2。有一块内存地址存放着对象 [1,2,3] ,变量a和b作为这块内存的引用,都存储了它的地址。
比较这两个,我更倾向于第二种理解。
如此,修改a的值b的值也会被修改。
第二句:c = list(a)
这一句实际上是完成了对a的复制的,但是复制的不够彻底,这种复制被称为“浅复制”。为什么呢?
这样看a的内容了。如果a中没有包含对象(a = [1,2,3] c = list(a) ),那么c的这种复制是成功的,c的内容和a是各自独立的。复制的时候又创建了一块新的内存,存放a指向的那块内存的内容。
但是,如果a中包含对象(a = [1,2,3,[45,34]], c = list(a)),那么c的这种复制只成功了一半。首先,还是会创建一块内存,存放a对象中的内容,可是a对象中的内嵌对象是不会被复制过来的,他会由a和c共享。也就是说,除了内嵌脆响之外,其他的元素都是相互独立的,只有内嵌对象是被共享的。修改内嵌对象的值c和a的值都会改变,修改其它非对象元素,c和a的值只会改变一个。
第三句:d = copy.deepcopy(a)
这是为了解决第二句的漏洞而设计的。使用这一句才能够把a中的所有元素和对象完全复制。d和a是独立的,修改a中的元素和对象的值都不会影响d中的元素和对象的值。这种复制称为“深复制”
这三种复制,不能说哪一种更好,灵活的运用在需要他们的地方,才能体现出各自的价值和优越性。
初学python,本文内容只作为学习过程的一个总结和理解的记录。其中不乏有用词不当的地方。有些地方也是自己实验过后得出的总结,可能还不够全面。如果您觉得我的理解有错误和偏差,希望您能够在留言中指出来,我会继续去探究印证。谢谢啦!