Как и когда соответственно использовать weakref в Python

Может быть несколько xpaths, которые приводят к тому же элементу, таким образом находя самый простой xpath, который приводит к узлу, не тривиально.

Однако довольно легко найти xpath к узлу. Просто повысьте дерева узла, пока Вы не читаете корневой узел и комбинируете имена узла, и у Вас есть допустимый xpath.

49
задан 3 revs, 2 users 99% 26 December 2016 в 14:46
поделиться

2 ответа

Yep, weakref's excellent here. Specifically, instead of:

self.children = {}

use:

self.children = weakref.WeakValueDictionary()

Nothing else needs change in your code. This way, when a child has no other differences, it just goes away -- and so does the entry in the parent's children map that has that child as the value.

Avoiding reference loops is up high on a par with implementing caches as a motivation for using the weakref module. Ref loops won't kill you, but they may end up clogging your memory, esp. if some of the classes whose instances are involved in them define __del__, since that interferes with the gc's module ability to dissolve those loops.

30
ответ дан 7 November 2019 в 11:55
поделиться

Я предлагаю использовать child.parent = weakref.proxy (self) . Это хорошее решение, чтобы избежать циклических ссылок в случае, когда время жизни (внешних ссылок на) родителя покрывает время жизни потомка . Напротив, используйте weakref для дочернего элемента (как предложил Алекс), когда время жизни ребенка покрывает время жизни родителя . Но никогда не используйте weakref , если оба parent и child могут быть живы без других.

Здесь эти правила проиллюстрированы примерами. Используйте родительский элемент weakref-ed, если вы храните корень в какой-либо переменной и передаете его, пока из него осуществляется доступ к дочерним элементам:

def Run():
  root, c1, c2 = Node(), Node(), Node()
  root.AddChild("first", c1)
  root.AddChild("second", c2)
  return root # Note that only root refers to c1 and c2 after return, 
              # so this references should be strong

Используйте дочерние элементы с слабой ссылкой, если вы привязываете все их к переменным, в то время как доступ к root осуществляется через них:

def Run():
  root, c1, c2 = Node(), Node(), Node()
  root.AddChild("first", c1)
  root.AddChild("second", c2)
  return c1, c2

Но ни один из них не будет работать для следующего:

def Run():
  root, c1, c2 = Node(), Node(), Node()
  root.AddChild("first", c1)
  root.AddChild("second", c2)
  return c1
18
ответ дан 7 November 2019 в 11:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: