python字典弱引用_一文看懂弱引用!Python中的weakref有什么用?

弱引用确实是一个不太好理解的概念,本文就用图画给大家讲解一下什么是弱引用第一部分:图画结合代码讲解弱引用概念

第二部分:weakref有什么用

第三部分:讲讲C语言中的弱引用

众所周知,在Python与java中都有垃圾收集器(garbage collector)存在,当一个实例的引用计数记为0时,gc就会自动的回收内存。

弱引用一言以蔽之,就是它不会增加被引用对象的引用计数。即使弱引用存在,垃圾回收器也会当没看见一样,认为这个对象是可回收的。但是我们确实可以通过弱引用到达一个对象。

第一部分:图画讲解

垃圾收集器会回收那些引用计数被记为0的对象,但是对非常复杂的数据结构,可能会存在互相引用而造成死锁的情况,如下图所示:

假设存在对象A,对象B,对象A,B互相强引用。

在这种情况下,A的引用计数为1,B的引用计数为1,垃圾回收器不会自动的回收它,我们只能去手动的运行垃圾回收器。

代码展示如下:

class Node:

def __init__(self):

self.parent=None

self.child=None

def add_child(self,child):

self.child=child

child.parent=self

def __del__(self):

print('deleted')

上面的代码定义了一个类。这个类的实例对象被删除时,会打印出“deleted”。

我们在解释器试一下...

可以看到del a时正确的打印出了deleted,说明垃圾回收器正确的回收了实例。

上面的演示,可以看到,当两个节点互相引用时,del a后,并没有显示deleted,说明实例没有被正确的回收。只有当我们手动的运行垃圾回收器时,实例才被正确的回收。

那么如下图这样,当A强引用B,而B对A是弱引用的时候,垃圾回收器会正确的回收吗?

代码编写如下:

import weakref

class Node:

def __init__(self):

self.parent=None

self.child=None

def add_child(self,child):

self.child=child

child.parent=weakref.ref(self)

def __del__(self):

print('deleted')

可以看到当两个节点实例变成不可达对象后,回收器正确的回收了内存。在gc眼中,此时A,B两个实例的引用就像下图这样。

A的引用计数已经为0,gc回收了它,B的引用计数也变为了0,gc再回收它。如此,内存被正确回收。

第二部分:weakref有什么用

弱引用的一个用处就是实现缓存。

弱引用简单的来说,当它引用的对象存在时,则对象可用,当对象不存在时,就返回None,说明对象不存在。程序不会因为对象不在就报错。

这正和缓存的性质一样,缓存就是一个有则用,无则重新获取的技术。

第三部分:C语言中的弱引用

C语言中同样有弱引用,它与程序的链接密切相关。

在《程序员的自我修养-装载,链接与库》一书中,3.5.5节讲到了弱引用。这里将原文给大家看一下:

在GCC中指定一个符号为弱引用,可以使用_attribute__((weakref))拓展关键字。我想上文对于链接器如何看待强弱引用讲的很清楚了。

谢谢你读完本文,有什么错误可以在评论区指正!!

欢迎点赞给作者一点鼓励!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值