python里weakref的使用

python是基于引用计数的垃圾回收机制,引用计数就涉及到循环引用这种麻烦的场景。简单代码如下:

class A:
    def __init__(self):
        self.b = B(self)
    def __del__(self):
        print('des A')


class B:
    def __init__(self, a):
        self.a = a
    def __del__(self):
        print('des B')

当创建a = A()之后,无论是del a 还是 a = None,两条析构的输出都不会马上打印出来,而是过一会,由python自行检测出有循环引用的垃圾没有回收,此时才回收,才会打印出两条日志输出。

此种典型情况,尽管可以交由python自行检测,但是考虑到性能和内存利用率,就特别需要弱引用来帮助降低垃圾回收的成本。可以改A:

class A:
    def __init__(self):
        self.b = B(weakref.ref(self))
    def __del__(self):
        print('des A')

也可以改B:

class B:
    def __init__(self, a):
        self.a = weakref.ref(a)
    def __del__(self):
        print('des B')

如果B永远是A的寄生类,那两种改法都ok,但是如果B有其他用处,比如:

class C:
    def __del__(self):
        print('des C')

>>> c = C()
>>> b = B(c)
>>> del c
>>> print(b.a)  ### dead ref

就会出现死引用。实际使用依情况而定。

发表于 2021年02月17日 09:39   评论:0   阅读:1646  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo