我尝试运行“Python基本参考”一书中的一个例子,其中涉及观察者模式,但是属性有一个问题。当AccountObserver执行__del__
时,出现错误-Object没有属性“observer”。我不知道代码有什么问题,所以如果有任何帮助我将不胜感激。在
class Account(object):
def __init__(self, name, balance):
self.name = name
self.balance = balance
self.observers = set()
def __del__(self):
for ob in self.observers:
ob.close()
del self.observers
def register(self, observer):
self.observers.add(observer)
def unregister(self, observer):
self.observers.remove(observer)
def notify(self):
for ob in self.observers:
ob.update()
def withdraw(self, amt):
self.balance -= amt
self.notify()
class AccountObserver(object):
def __init__(self, theaccount):
self.theaccount = theaccount
self.theaccount.register(self)
def __del__(self):
self.theaccount.unregister(self)
del self.theaccount
def update(self):
print("Balance is %0.2f" % self.theaccount.balance)
def close(self):
print("Account no longer in use")
a = Account("Ketty", 200000)
a_mama = AccountObserver(a)
a_tata = AccountObserver(a)
a.unregister(a_mama)
a.withdraw(10)
以及输出:
^{pr2}$
当解释器退出时,Python会清除模块。此时,所有实例和类都将被删除,这意味着
Account.__del__
可以在AccountObserver.__del__
之前运行。清除类的顺序取决于全局命名空间字典的顺序,由于使用了random hash seed,全局命名空间字典的顺序是随机的。Account.__del__
删除self.observers
,因此以后对account.unregister()
的任何调用都将引发一个AttributeError
。在您的代码依赖于当模块退出时仍然存在的类和属性。这意味着您可以同时得到}因为
KeyError
错误(因为a_mama
已经被注销),或者{self.observers
属性已经被清除(因为Account.__del__
清除了它)。在在^{} documentation 中有一个很大的警告:
解决方法是使您的
__del__
方法在遇到此类异常时更加健壮:相关问题 更多 >
编程相关推荐