Когда A -> B и B -> A, у вас есть эталонные циклы. Хороший способ обойти это - заставить детей использовать слабые ссылки, чтобы указать на родителя. Примерно так:
import weakref
class Node():
parent = None
child = None
@property
def parent(self):
parent = self._parent()
if parent is not None:
return parent
raise ValueError("parent has been deleted")
@parent.setter # python 2.6+
def parent(self, parent):
self._parent = weakref.ref(parent)
Теперь у узла нет прямой ссылки на его родительский элемент, и когда вы удаляете дочерний элемент, он действительно исчезает *. (Вам может понадобиться использовать тот же метод для parent_arc.)
* Обратите внимание, что даже если Python освободит объекты быстрее, если не существует циклов ссылок, он может не вернуть эту память обратно ОС.