Python-Observer模式-Object没有属性
我试着运行《Python基本参考》一书中的一个例子,其中涉及观察者模式,但属性有一个问题。当AccountObserver执行_del__时,将引发错误-对象没有属性“Observer”。我不知道代码出了什么问题,所以非常感谢您的帮助Python-Observer模式-Object没有属性,python,design-patterns,python-3.x,finalizer,Python,Design Patterns,Python 3.x,Finalizer,我试着运行《Python基本参考》一书中的一个例子,其中涉及观察者模式,但属性有一个问题。当AccountObserver执行_del__时,将引发错误-对象没有属性“Observer”。我不知道代码出了什么问题,所以非常感谢您的帮助 class Account(object): def __init__(self, name, balance): self.name = name self.balance = balance self.o
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)
以及输出:
Balance is 199990.00
Account no longer in use
Exception ignored in: <bound method AccountObserver.__del__ of <__main__.AccountObserver object at 0x024BF9F0>>
Traceback (most recent call last):
File "F:\Projects\TestP\src\main.py", line 28, in __del__
File "F:\Projects\TestP\src\main.py", line 13, in unregister
AttributeError: 'Account' object has no attribute 'observers'
Exception ignored in: <bound method AccountObserver.__del__ of <__main__.AccountObserver object at 0x024BFEB0>>
Traceback (most recent call last):
File "F:\Projects\TestP\src\main.py", line 28, in __del__
File "F:\Projects\TestP\src\main.py", line 13, in unregister
AttributeError: 'Account' object has no attribute 'observers'
当解释器退出时,Python清除模块。此时,所有实例和类都将被删除,这意味着Account.\uu del\uuuuuuuu可以在AccountObserver.\uu del\uuuuu之前运行。清除类的顺序取决于全局命名空间字典顺序,由于使用了。Account.\uuu del\uuuu删除self.observators,因此以后调用Account.unregister将引发AttributeError 您的代码依赖于当模块退出时仍然存在的类和属性。这意味着您可以同时获得KeyError错误(因为已注销帐户),或者AttributeError错误(因为self.observators属性已被清除),因为Account.\u del\u已清除它 有一个巨大的脂肪警告,在: 警告:由于调用u_del_u___)方法的情况不稳定,在执行过程中发生的异常将被忽略,并将警告打印到sys.stderr。此外,当调用uu del u以响应被删除的模块时,例如,当程序执行完成时,u del u方法引用的其他全局变量可能已经被删除或正在被拆除,例如,导入机器关闭。出于这个原因,_del_u_________________________________。从版本1.5开始,Python保证在删除其他全局变量之前,从其模块中删除名称以单个下划线开头的全局变量;如果不存在对此类全局变量的其他引用,这可能有助于确保在调用_del___方法时导入的模块仍然可用 解决方法是使您的_del____________)方法在遇到此类异常时更为稳健:
def unregister(self, observer):
try:
self.observers.remove(observer)
except (KeyError, AttributeError):
# no such observer, or the observers set has already been cleared
您正在使用Python3吗?Py2.7。。我无法复制it@MartijnPieters我可以使用python3.4,AttributeError:'Account'对象没有属性'Observators'@padraiccnningham:我在3.4 shell中运行了这个。现在将尝试使用一个单独的文件。@PadraicCunningham:ah,由于清除顺序,已复制。python 2和python 3之间有什么区别?@PadraicCunningham:python 3默认使用随机哈希种子,因此字典顺序更不可预测。它也可以在Python2中发生,但是字典顺序更稳定,所以除非您使用-R开关运行Python,否则在这里不会发生这种情况。非常感谢您的及时响应和解释。