J'ai un code où les instances de classes ont un parent<->enfant références les uns aux autres, par exemple:
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()
Je pense que cela crée des références circulaires telles que root
, c1
et c2
ne sera pas libéré après Run() est terminée, non?. Alors, comment les amener à être libéré? Je pense que je peux faire quelque chose comme root.children.clear()
ou self.parent = None
- mais si je ne sais pas quand le faire?
Est-ce un moment approprié pour utiliser le weakref module? Ce qui, exactement, je ne weakref'ify? l' parent
d'attribut? L' children
d'attribut? L'ensemble de l'objet? Tous les ci-dessus? Je vois parler de la WeakKeyDictionary et weakref.proxy, mais il n'est pas clair pour moi comment ils doivent être utilisés, le cas échéant, dans ce cas.
C'est aussi sur python2.4 (pouvez pas mettre à niveau).
Mise à jour: Exemple et Résumé
Quels sont les objets à weakref-identifier dépend de l'objet qui peut vivre sans l'autre, et quels sont les objets dépendent les uns des autres. L'objet qui vie la plus longue doit contenir weakrefs à la courte durée de vie des objets. De même, weakrefs ne doit pas être faite à ses dépendances, - si elles le sont, la dépendance pourrait silencieusement disparaître, même si c'est encore nécessaire.
Si, par exemple, vous avez une structure en arbre, root
, qui a des enfants, kids
, mais peut exister sans les enfants, puis l' root
objet doit utiliser weakrefs pour son kids
. C'est également le cas si l'enfant de l'objet dépend de l'existence de l'objet parent. Ci-dessous, l'objet enfant nécessite un parent afin de calculer la profondeur, d'où la forte-ref pour parent
. Les membres de l' kids
attribut est facultatif, cependant, de sorte weakrefs sont utilisés pour prévenir une référence circulaire.
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 count
root = Node()
root.kids["one"] = Node()
root.kids["two"] = Node()
# do what you will with root or sub-trees of it.
Pour inverser la relation autour de nous, nous avons quelque chose comme ci-dessous. Ici, l' Facade
classes nécessitent Subsystem
exemple de travail, de sorte qu'ils utilisent un forte-ref pour le sous-système dont ils ont besoin. Subsystem
s, cependant, ne nécessitent pas un Facade
de travail. Subsystem
s, il suffit de fournir un moyen d'avertir Facade
s à propos des uns et des autres actions.
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