import weakref class weakattr(object): """ weakattr - a weakly-referenced attribute. When the attribute is no longer referenced, it 'disappears' from the instance. Great for cyclic references. """ __slots__ = ["dict", "errmsg"] def __init__(self, name = None): self.dict = weakref.WeakValueDictionary() if name: self.errmsg = "%%r has no attribute named %r" % (name,) else: self.errmsg = "%r has no such attribute" def __repr__(self): return "" % (id(self),) def __get__(self, obj, cls): if obj is None: return self try: return self.dict[id(obj)] except KeyError: raise AttributeError(self.errmsg % (obj,)) def __set__(self, obj, value): self.dict[id(obj)] = value def __delete__(self, obj): try: del self.dict[id(obj)] except KeyError: raise AttributeError(self.errmsg % (obj,)) # # example # >>> class x(object): ... next = weakattr() ... def __init__(self): ... self.next = self ... def __del__(self): ... print "g'bye" ... >>> >>> y = x() >>> y.next <__main__.x object at 0x009EFA50> >>> del y >>> gc.collect() g'bye 0