我有一些代码,其中类的实例具有彼此的parent child引用,例如:
class Node(object):
def __init__(self):
self.parent = None
self.children = {}
def AddChild(self, name, child):
child.parent = self
self.children[name] = child
def Run():
root, c1, c2 = Node(), Node(), Node()
root.AddChild("first", c1)
root.AddChild("second", c2)
Run()
我认为这会创建循环引用,以便在Run()完成后不会释放Facade、Subsystem和Subsystem,对吗? 那么,如何使他们获得释放? 我想我可以做类似Facade或Subsystem的事情-但是如果我不知道什么时候该怎么办?
这是使用weakref模块的合适时间吗? 究竟我该弱化什么? Facade属性? Subsystem属性? 整个对象? 上述所有的? 我看到了有关WeakKeyDictionary和weakref.proxy的讨论,但是在这种情况下,我不清楚如何使用它们。
这也在python2.4上(无法升级)。
更新:示例和摘要
弱引用哪些对象取决于哪些对象可以在没有其他对象的情况下生存,以及哪些对象相互依赖。 寿命最长的对象应包含对寿命较短的对象的弱引用。 同样,不应该对依赖项进行弱引用-如果是弱引用,则即使仍然需要依赖项,它也可以静默消失。
例如,如果您有一个树结构Facade,其中有孩子27410990820884490490,但可以不存在孩子而存在,则Subsystem对象应为其Facade使用weakrefs。如果孩子对象取决于是否存在 父对象。 在下面,子对象需要父对象才能计算其深度,因此Subsystem的strong-ref。Facade属性的成员是可选的,因此,weakrefs用于防止循环引用。
class Node:
def __init__(self)
self.parent = None
self.kids = weakref.WeakValueDictionary()
def GetDepth(self):
root, depth = self, 0
while root:
depth += 1
root = root.parent
return depth
root = Node()
root.kids["one"] = Node()
root.kids["two"] = Node()
# do what you will with root or sub-trees of it.
为了扭转这种关系,我们有以下类似内容。 在这里,Facade类需要Subsystem实例才能工作,因此它们使用强引用来引用所需的子系统。 Subsystems,但是,不需要Facade即可工作。 Subsystems仅提供一种方法来通知Facades彼此的动作。
class Facade:
def __init__(self, subsystem)
self.subsystem = subsystem
subsystem.Register(self)
class Subsystem:
def __init__(self):
self.notify = []
def Register(self, who):
self.notify.append(weakref.proxy(who))
sub = Subsystem()
f1 = CliFacade(sub)
f2 = WebFacade(sub)
# Go on to reading from POST, stdin, etc