访问父对象而不引用它

时间:2014-09-05 08:14:51

标签: python garbage-collection

我遇到了一个引用引用问题的问题,即对象没有被删除,因为有一个"不必要的"成员引用父(循环引用)。

以下是缩短版本:

class User(object):
    __slots__ = ("driver")
    def __init__(self, *params):
        self.driver = getDriverType(params)()
        self.driver.parent = self

    def getFancyObject(self):
        return FancyObject(self)

class Driver(object):
    def __init__(self):
        self.parent = None
    def specialCode(self):
        self.parent.getFancyObject()
        ...
        # driver-specific code doing something with fancyObject

为了做特定于驱动程序的东西,我仍然只需要父提供的高级功能(再次,通过驱动程序提供的功能)。我可以不使用FancyObject实例,但是必须输入更多代码。

当然,创建对父级的引用会阻止父级和驱动程序的销毁,这不仅会占用Python VM中的RAM,还会占用此驱动程序处理的硬件资源。每当User的实例仍然存在时,这会迅速升级为无响应的应用和内存异常。

毋庸置疑,__slots__类中的User会阻止在该类上创建weakref.ref。

不可否认,我已经完成了这个问题,我只能看到一个很好的Pythonic解决方案。

如何在不创建阻止对象gc的引用的情况下实现所需的功能?

1 个答案:

答案 0 :(得分:2)

使用__slots__定义对象的事实并不排除创建对该对象的弱引用的能力。但它确实意味着您需要明确定义__weakref__属性:

class User:
    __slots__ = ('driver','__weakref__')
    def __init__(self):
        self.driver = Driver()
        self.driver.parent = weakref.ref(self) # or weakref.proxy(self)
    def __del__(self):
        print('user deleted')

class Driver:
    def __init__(self):
        self.parent = None
    def __del__(self):
        print('driver deleted')

>>> u = User()
>>> del u
user deleted
driver deleted