Spaces:
Running
on
T4
Running
on
T4
import weakref | |
class WeakList(list): | |
def __init__(self, seq=()): | |
list.__init__(self) | |
self._refs = [] | |
self._dirty=False | |
for x in seq: self.append(x) | |
def _mark_dirty(self, wref): | |
self._dirty = True | |
def flush(self): | |
self._refs = [x for x in self._refs if x() is not None] | |
self._dirty=False | |
def __getitem__(self, idx): | |
if self._dirty: self.flush() | |
return self._refs[idx]() | |
def __iter__(self): | |
for ref in self._refs: | |
obj = ref() | |
if obj is not None: yield obj | |
def __repr__(self): | |
return "WeakList(%r)" % list(self) | |
def __len__(self): | |
if self._dirty: self.flush() | |
return len(self._refs) | |
def __setitem__(self, idx, obj): | |
if isinstance(idx, slice): | |
self._refs[idx] = [weakref.ref(obj, self._mark_dirty) for x in obj] | |
else: | |
self._refs[idx] = weakref.ref(obj, self._mark_dirty) | |
def __delitem__(self, idx): | |
del self._refs[idx] | |
def append(self, obj): | |
self._refs.append(weakref.ref(obj, self._mark_dirty)) | |
def count(self, obj): | |
return list(self).count(obj) | |
def extend(self, items): | |
for x in items: self.append(x) | |
def index(self, obj): | |
return list(self).index(obj) | |
def insert(self, idx, obj): | |
self._refs.insert(idx, weakref.ref(obj, self._mark_dirty)) | |
def pop(self, idx): | |
if self._dirty: self.flush() | |
obj=self._refs[idx]() | |
del self._refs[idx] | |
return obj | |
def remove(self, obj): | |
if self._dirty: self.flush() # Ensure all valid. | |
for i, x in enumerate(self): | |
if x == obj: | |
del self[i] | |
def reverse(self): | |
self._refs.reverse() | |
def sort(self, cmp=None, key=None, reverse=False): | |
if self._dirty: self.flush() | |
if key is not None: | |
key = lambda x,key=key: key(x()) | |
else: | |
key = apply | |
self._refs.sort(cmp=cmp, key=key, reverse=reverse) | |
def __add__(self, other): | |
l = WeakList(self) | |
l.extend(other) | |
return l | |
def __iadd__(self, other): | |
self.extend(other) | |
return self | |
def __contains__(self, obj): | |
return obj in list(self) | |
def __mul__(self, n): | |
return WeakList(list(self)*n) | |
def __imul__(self, n): | |
self._refs *= n | |
return self |