Python中的weakref的简单用法示例

举报
悲恋花丶无心之人 发表于 2021/02/03 01:14:52 2021/02/03
【摘要】 目录 一、概念 二、解决问题 三、代码及解释 四、结论 一、概念 对一个对象的弱引用(weak reference)。相对于通常的引用来说,如果一个对象有一个常规的引用,它是不会被垃圾收集器销毁的,但是如果一个对象只剩下一个弱引用,那么它可能被垃圾收集器收回。 二、解决问题 父亲节点的指针指向孩子节点,孩子节点又指向父亲节点,这构成了循环引用(circuc...

目录

一、概念

二、解决问题

三、代码及解释

四、结论


一、概念

对一个对象的弱引用(weak reference)。相对于通常的引用来说,如果一个对象有一个常规的引用,它是不会被垃圾收集器销毁的,但是如果一个对象只剩下一个弱引用,那么它可能被垃圾收集器收回


二、解决问题

父亲节点的指针指向孩子节点,孩子节点又指向父亲节点,这构成了循环引用(circuclar reference),所以每个对象的引用计数(reference count)都不可能变成 0


三、代码及解释

1.use_weakA类中parent方法,决定self._parent被赋值为parent对象还是parent对象的弱引用

2.sys.getrefcount(parent):返回parent对象引用计数

3.weakref.ref(a):返回a弱引用(代码这里对child对象传入了parent对象


  
  1. import weakref
  2. import sys
  3. class A:
  4. def __init__(self, data: str, use_weakref=None):
  5. """
  6. :param data: string
  7. :param use_weakref: flag for using weak reference
  8. """
  9. self.data = data
  10. self.use_weakref = use_weakref
  11. self.children = []
  12. def __repr__(self):
  13. """
  14. :return: print A object content
  15. """
  16. return '{}'.format(self.data)
  17. def __del__(self):
  18. """
  19. :return: delete massage
  20. """
  21. print('{}.__del__'.format(self.data))
  22. @property
  23. def parent(self):
  24. return self._parent
  25. @parent.setter
  26. def parent(self, a):
  27. """
  28. :param a: parent object
  29. :return: self._parent
  30. """
  31. if self.use_weakref:
  32. self._parent = weakref.ref(a)
  33. else:
  34. self._parent = a
  35. def add_child(self, child):
  36. """
  37. :param child: child object belongs to A class
  38. :return: self.children = [child]
  39. child's parent is parent self.
  40. """
  41. self.children.append(child)
  42. child.parent = self
  43. if __name__ == '__main__':
  44. use_weakref = True # True or False, determine if `weakref.ref(parent)` or just `parent`
  45. parent = A('parent', use_weakref)
  46. # print reference count of `parent`
  47. print(sys.getrefcount(parent)) # 2
  48. child = A('child', use_weakref)
  49. parent.add_child(child) # Add child
  50. # print reference count of parent,
  51. # if `weakref.ref(parent)` in child,
  52. # the reference count will not be changed;
  53. # else `parent` in child,
  54. # the reference count will add 1.
  55. print(sys.getrefcount(parent)) # 2(not changed) or 3
  56. print(child.parent)
  57. del parent # delete parent object
  58. # (1)if not use weak reference,
  59. # `print(child.parent)-->parent` although `child.__del__` and `parent.__del__` has been printed.
  60. # (2)if use weak reference,
  61. # `print(child.parent)--><weakref at 0x00000xxxxxxxxxx; dead>,
  62. # so weak reference is able to solve the circular reference when `garbage collection` happened.
  63. print(child.parent)

结果:

(1)如果use_weakrefTrue,则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_weakrefFalse,则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

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。