python中的变量与垃圾回收
python中的变量和java中的变量本质是不一样的,python中的变量实质上是一个指针(指针的大小固定的)
a = 1
a = "abc"
#1.a贴在1上面
#2.先生成对象,然后便利贴
a= [1, 2, 3]
b=a
print(id(a), id(b)) #a和b是同一个对象
print (a is b)
#结果
140519998094152 140519998094152
True
is 和 ==的区别
is可以用来判断id是否相等
a = [1, 2, 3, 4]
b = [1 ,2, 3, 4]
140519998162248 140519998864264
False
对于这种赋值,虽然所赋值是相同的,但是他们的id不同,即他们是不同的对象,a is b 即为false ,但是有个特例: a = 1 b = 1 时他们的id相同。其实这是python内部的优化机制,对于小整数和小的字符串来说,python在前边定义一个对象时,下次在遇到时会直接调用前边生成的对象,而不会去重新申请一个。
a = [1, 2, 3, 4]
b = [1 ,2, 3, 4]
print(id(a), id(b))
print(a == b)
140519999248264 140519999070600
True
他们的对象内存地址不一样,但是,a和b里的值是相等的,这是由于a和b都为list,而list里有内置的魔法函数eq通过eq魔法函数可以判断里边两个的值是否相同,若相同则返回True
class People:
pass
person = People()
if type(person) is People: #在判断persion是一个什么类时就可以使用is 切记不可使用==, 或者使用isinstance()
print("yes")
del语句和垃圾回收
python中垃圾回收的算法回收的算法是采用引用计数,当程序中有一个变量引用该python对象时,python会自动保证该对象引用计数为1;当程序中有两个变量引用该python对象时,python会自动保证该对象计数器为2, 以此类推,当一个对象的引用计数器变为0 时,则说明程序中不再有变量对其进行引用,因此python就会回收该对象。
大多数情况,python的ARC都能准确,高效的回收系统中的每一个对象。但如果系统中出现循环引用时,比如a对象持有一个实例变量引用对象b,而b对象又持有一个实例变量引用对象a,此时 两个对象的计数器都为1, 而实际上python不再需要这两个对象,也没有程序在引用他们,系统回收他们时python的垃圾回收器就没有那儿快,要等到专门的循环垃圾回收器(Cyclic Garbage Collector)来检测并回收这种引用循环
当一个对象被垃圾回收式,python就会自动调用该对象的del方法
对一个对象执行del操作,该变量不一定会回收,只有当对象的引用计数器变为0时,该对象才会被回收。因此,如果一个对象有多个变量引用它,那么del其中一个变量是不会回收该对象的。
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
#定义析构函数
def __del__(self):
print('del删除对象')
#创建一个Item对象,将其赋给im变量
im = Item('鼠标', 29.8)
x = im
#打印im所引用的对象
del im
print("---------------")
结果为
---------------
del删除对象
若注释掉 x = im 结果则改变为如下
del删除对象
---------------
当没有注释掉x = im时, item对象被两个变量所引用,所以在执行完del im时并不会去回收item对象,所以先输出--------,当程序完全执行完成后,引用item的对象的变量被释放,然后系统便会执行del方法,回收item对象。
当 x = im被注释后,只有一个变量去引用item对象,所以在执行完后程序变回去调用del方法,回收item对象,然后在继续向下执行 输出-----