Python中的weakref的简单用法示例
目录
一、概念
对一个对象的弱引用(weak reference)。相对于通常的引用来说,如果一个对象有一个常规的引用,它是不会被垃圾收集器销毁的,但是如果一个对象只剩下一个弱引用,那么它可能被垃圾收集器收回。
二、解决问题
父亲节点的指针指向孩子节点,孩子节点又指向父亲节点,这构成了循环引用(circuclar reference),所以每个对象的引用计数(reference count)都不可能变成 0。
三、代码及解释
1.use_weak:A类中parent方法,决定self._parent被赋值为parent对象还是parent对象的弱引用
2.sys.getrefcount(parent):返回parent对象的引用计数
3.weakref.ref(a):返回a的弱引用(代码这里对child对象传入了parent对象)
-
import weakref
-
import sys
-
-
-
class A:
-
def __init__(self, data: str, use_weakref=None):
-
"""
-
:param data: string
-
:param use_weakref: flag for using weak reference
-
"""
-
self.data = data
-
self.use_weakref = use_weakref
-
self.children = []
-
-
def __repr__(self):
-
"""
-
:return: print A object content
-
"""
-
return '{}'.format(self.data)
-
-
def __del__(self):
-
"""
-
:return: delete massage
-
"""
-
print('{}.__del__'.format(self.data))
-
-
@property
-
def parent(self):
-
return self._parent
-
-
@parent.setter
-
def parent(self, a):
-
"""
-
:param a: parent object
-
:return: self._parent
-
"""
-
if self.use_weakref:
-
self._parent = weakref.ref(a)
-
else:
-
self._parent = a
-
-
def add_child(self, child):
-
"""
-
:param child: child object belongs to A class
-
:return: self.children = [child]
-
-
child's parent is parent self.
-
"""
-
self.children.append(child)
-
child.parent = self
-
-
-
if __name__ == '__main__':
-
-
use_weakref = True # True or False, determine if `weakref.ref(parent)` or just `parent`
-
-
parent = A('parent', use_weakref)
-
# print reference count of `parent`
-
print(sys.getrefcount(parent)) # 2
-
-
child = A('child', use_weakref)
-
-
parent.add_child(child) # Add child
-
# print reference count of parent,
-
# if `weakref.ref(parent)` in child,
-
# the reference count will not be changed;
-
# else `parent` in child,
-
# the reference count will add 1.
-
print(sys.getrefcount(parent)) # 2(not changed) or 3
-
-
print(child.parent)
-
-
del parent # delete parent object
-
# (1)if not use weak reference,
-
# `print(child.parent)-->parent` although `child.__del__` and `parent.__del__` has been printed.
-
# (2)if use weak reference,
-
# `print(child.parent)--><weakref at 0x00000xxxxxxxxxx; dead>,
-
# so weak reference is able to solve the circular reference when `garbage collection` happened.
-
print(child.parent)
-
-
结果:
(1)如果use_weakref是True,则parent对象引用计数不变(为2),可成功删除parent,避免循环引用(可以看到引用从to 'A' 变成了dead)
2
2
<weakref at 0x00000163566F8318; to 'A' at 0x0000016356717DD8>
parent.__del__
<weakref at 0x00000163566F8318; dead> # `print(child.parent)` after `del parent`,delete parent object sucess!
child.__del__
(2)如果use_weakref是False,则parent对象引用计数加1(由2变为3),不能成功删除parent,循环引用仍旧存在
2
3
parent
parent # `print(child.parent)` after `del parent`,delete parent object failed!
child.__del__
parent.__del__
四、结论
由此可见, 通过weakref来解决循环引用,即如果一个对象只剩下一个弱引用,那么它是可以被垃圾回收的。
文章来源: nickhuang1996.blog.csdn.net,作者:悲恋花丶无心之人,版权归原作者所有,如需转载,请联系作者。
原文链接:nickhuang1996.blog.csdn.net/article/details/105726547
- 点赞
- 收藏
- 关注作者
评论(0)