weakattr - a weakly-referenced attribute. When the attribute is no longer referenced, it 'disappears' from the instance. Great for cyclic references.
| 2 | |
| 3 | |
| 4 | class weakattr(object): |
| 5 | """ |
| 6 | weakattr - a weakly-referenced attribute. When the attribute is no longer |
| 7 | referenced, it 'disappears' from the instance. Great for cyclic references. |
| 8 | """ |
| 9 | __slots__ = ["dict", "errmsg"] |
| 10 | |
| 11 | def __init__(self, name = None): |
| 12 | self.dict = weakref.WeakValueDictionary() |
| 13 | if name: |
| 14 | self.errmsg = "%%r has no attribute named %r" % (name,) |
| 15 | else: |
| 16 | self.errmsg = "%r has no such attribute" |
| 17 | |
| 18 | def __repr__(self): |
| 19 | return "<weakattr at 0x%08X>" % (id(self),) |
| 20 | |
| 21 | def __get__(self, obj, cls): |
| 22 | if obj is None: |
| 23 | return self |
| 24 | try: |
| 25 | return self.dict[id(obj)] |
| 26 | except KeyError: |
| 27 | raise AttributeError(self.errmsg % (obj,)) |
| 28 | |
| 29 | def __set__(self, obj, value): |
| 30 | self.dict[id(obj)] = value |
| 31 | |
| 32 | def __delete__(self, obj): |
| 33 | try: |
| 34 | del self.dict[id(obj)] |
| 35 | except KeyError: |
| 36 | raise AttributeError(self.errmsg % (obj,)) |
| 37 | |
| 38 | # |
| 39 | # example |