Вы должны сохранить ссылку на своего родителя, но вы можете сделать так, чтобы это волшебство происходило автоматически:
from weakref import ref
class MyClass(object):
def __setattr__(self, key, value):
self.__dict__[key] = value
try:
value._parent = ref(self)
except AttributeError:
raise TypeError('MyClass cannot have children of type ' +
type(value).__name__)
def __delattr__(self, key):
v = self.__dict__[key]
del self.__dict__[key]
try:
v._parent = None
except AttributeError:
raise TypeError('Child of MyClass is mysteriously '
'missing its parent')
class SomeObject(object):
_parent = None
@property
def parent(self):
if self._parent is not None:
return self._parent()
return None
>>> a = MyClass()
>>> a.b = SomeObject()
>>> print a.b.parent
<__main__.MyClass at 0x8ce60f0>
>>> b = a.b
>>> del a.b
>>> print b.parent
None
Переопределяя операторы __setattr__
и __delattr__
, вы можете контролировать взгляд ребенка на егородитель и убедитесь, что соединение всегда правильно.Кроме того, это позволяет избежать использования неуклюжих add
/ remove
методов;методы, которые вы можете случайно забыть использовать.Это ограничивает ваши объекты наличием точно одного родителя, но для этих типов моделей это, как правило, желательно.
Наконец, я рекомендую вместо того, чтобы хранить ссылку на родительский объект напрямую,вы держите слабую ссылку.Это позволяет избежать циклических ссылок, которые могут запутать сборщик мусора (a
содержит ссылку на b
, которая содержит ссылку на a
. Их счетчик ссылок никогда не идет в 0, поэтому они несборка мусора).