Tôi đang thực hiện một mô hình quan sát-quan sát được trong python:làm thế nào để thực hiện đúng Observer trong python khi người quan sát là [nên] phá hủy
Đây là lớp học Quan sát:
class Observable(object):
def __init__(self, value):
self.value = value
self.observers = []
def set(self, value):
old = self.value
self.value = value
self.notifyObservers(old, self.value)
def get(self):
return self.value
def addObserver(self, o):
self.observers.append(o)
def removeObserver(self, o):
if o in self.observers:
self.observers.remove(o)
def notifyObservers(self, old, new):
for o in self.observers:
o.valueChanged(old, new)
và điều này là người quan sát:
class Observer(object):
def __init__(self, foo):
self.foo = foo
self.foo.addObserver(self)
def __del__(self):
print('Observer.__del__ called')
self.foo.removeObserver(self)
def valueChanged(self, old, new):
print('foo changed from %s to %s' % (old, new))
Mã hoạt động như mong đợi.
Nhưng tôi cần Observer
bị hủy (tức là khi nó không được đề cập đến, nó sẽ tự xóa chính nó khỏi danh sách các nhà quan sát trong đối tượng Observable
).
Vấn đề là với mã này, Observer.__del__
không bao giờ được gọi nếu số Observer
nằm trong danh sách các nhà quan sát của một số đối tượng Observable
.
Lưu ý rằng tôi không nhất thiết phải tiêu diệt các Observer
một cách rõ ràng, nó cũng sẽ đi unreferenced vì giao biến, do đó gọi removeObserver()
một cách rõ ràng trước khi phá hủy là không khả thi.
Nếu tôi nhận xét ra self.foo.addObserver(self)
, thì không có tham chiếu bổ sung nào cho Observer
và gọi del
trên đó sẽ gọi Observer.__del__
.
Các testcase cho kịch bản này là:
foo = Observable(23)
bar = Observer(foo)
foo.set(44)
bar = None
foo.set(1)
nó có hai kết quả:
- nếu
self.foo.addObserver(self)
không được nhận xét ra, nó infoo changed from 23 to 44
vàfoo changed from 44 to 1
- nếu
self.foo.addObserver(self)
là nhận xét ra, nó inObserver.__del__ called
Bạn đã xem xét yếu kém? Tham chiếu yếu được thiết kế để giải quyết chính xác vấn đề này và đã là một tính năng của Python kể từ 2.4. –