내가 파이썬에서 관찰자 관찰 패턴을 구현 해요 :은 관찰자가있을 때 제대로 파이썬에서 관찰자를 구현하는 방법을 [해야] 파괴
이 관찰 클래스 :
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)
이 옵서버입니다.
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))
코드가 예상대로 작동합니다.
그러나 내가 참조 할 수 없게 될 때 Observer
개체가 필요합니다. Observable
개체의 관찰자 목록에서 삭제되어야합니다.
이 코드의 경우 Observer
이 일부 Observable
개체의 옵저버 목록에있는 경우 Observer.__del__
이 호출되지 않습니다. 내가 반드시 명시 적으로 Observer
을 파괴하지 않는
주, 그것은 또한 따라서 가능한 아니다 파괴 명시 적으로 이전 removeObserver()
를 호출하기 때문에 변수 할당의 참조되지 않은 이동합니다.
내가 Observer
에 대한 추가 참조가 없으면 del
을 호출하면 Observer.__del__
이 호출됩니다. 이 시나리오
테스트 케이스는 다음과 같습니다
foo = Observable(23)
bar = Observer(foo)
foo.set(44)
bar = None
foo.set(1)
이 두 가지 결과가 있습니다 주석 처리되지
self.foo.addObserver(self)
경우self.foo.addObserver(self)
이 주석하는 경우, 그것은foo changed from 23 to 44
및foo changed from 44 to 1
- 을 출력을, 그것은 인쇄한다
Observer.__del__ called
약한 부분을 보았습니까? 약한 참조는 정확하게이 문제를 해결하도록 설계되었으며 2.4 이후 Python의 기능이었습니다. –