Bạn có thể thực hiện điều đó cho mình, tương tự như cách bạn đã làm, nhưng với một lớp con danh sách mà các cuộc gọi flush() trước khi cố gắng truy cập vào một mục. Rõ ràng là bạn không muốn làm điều này trên mọi truy cập, nhưng bạn có thể tối ưu hóa điều này bằng cách thiết lập một cuộc gọi lại trên tham chiếu yếu để đánh dấu danh sách bẩn khi một cái gì đó chết. Sau đó, bạn chỉ cần tuôn ra danh sách khi một cái gì đó đã chết kể từ lần truy cập cuối cùng.
Dưới đây là danh sách lớp được triển khai bằng phương pháp này. (Lưu ý rằng nó không được thử nghiệm nhiều, và một số phương pháp không được thực hiện rất hiệu quả (ví dụ: những phương thức chỉ chuyển đổi thành danh sách thực và gọi phương thức đó), nhưng nó phải là điểm khởi đầu hợp lý:
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
[chỉnh sửa] thêm một thực hiện danh sách đầy đủ hơn
bạn có thể xin định nghĩa "chết", "tham khảo", "tuôn ra", "loại bỏ bằng tay"? câu hỏi này thực sự không có ý nghĩa gì nếu không có những câu hỏi đó. – hop
die = tham chiếu yếu trở thành không hợp lệ ("đã chết"). tham chiếu = tham chiếu yếu (http://docs.python.org/library/weakref.html). flush = remove manually = lặp qua tất cả các tham chiếu trong danh sách loại bỏ những tham chiếu không hợp lệ. – Dan
vẫn không rõ ràng, trừ khi bạn đã biết phải làm gì – hop