我在python中探索不同的概念,我碰巧阅读了一个可以用于责任链设计模式的协同程序的例子。我写了以下代码:
from functools import wraps
def coroutine(function):
@wraps(function)
def wrapper(*args, **kwargs):
generator = function(*args, **kwargs)
next(generator)
return generator
return wrapper
@coroutine
def PlatinumCustomer(successor=None):
cust = (yield)
if cust.custtype == 'platinum':
print "Platinum Customer"
elif successor is not None:
successor.send(cust)
@coroutine
def GoldCustomer(successor=None):
cust = (yield)
if cust.custtype == 'gold':
print "Gold Customer"
elif successor is not None:
successor.send(cust)
@coroutine
def SilverCustomer(successor=None):
cust = (yield)
if cust.custtype == 'silver':
print "Silver Customer"
elif successor is not None:
successor.send(cust)
@coroutine
def DiamondCustomer(successor=None):
cust = (yield)
if cust.custtype == 'diamond':
print "Diamond Customer"
elif successor is not None:
successor.send(cust)
class Customer:
pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer())))
def __init__(self,custtype):
self.custtype = custtype
def HandleCustomer(self):
try:
self.pipeline.send(self)
except StopIteration:
pass
if __name__ == '__main__':
platinum = Customer('platinum')
gold = Customer('gold')
silver = Customer('silver')
diamond = Customer('diamond')
undefined = Customer('undefined')
platinum.HandleCustomer()
gold.HandleCustomer()
undefined.HandleCustomer()
我在这里尝试做的是尝试创建一个责任链模式解决方案,以处理不同类型的客户(白金,黄金,钻石,银)。
因为客户有一个管道,我已经提到了处理不同客户的顺序。 Customer()。HandleCustomer将通过管道发送自己的实例,该管道将检查其custtype是否匹配,然后相应地处理它,或者将其发送给它的后继者(如果可用)
问题:问题是,当我运行上面的脚本时,它将处理第一个铂金客户,但不处理黄金或未定义。我假设这是因为他已经到了发电机的末端。如何修改代码,以便每当它成为客户的新实例时,它将从一开始就经历管道?
答案 0 :(得分:4)
你的协同程序必须永远循环才能处理连续的调用,如:
@coroutine
def PlatinumCustomer(successor=None):
while 1: # <---- this is missing from your coroutines
cust = (yield)
if cust.custtype == 'platinum':
print "Platinum Customer"
elif successor is not None:
successor.send(cust)
并处理未定义的&#39;类型,你需要一个最终的全能处理程序:
@coroutine
def UndefinedCustomer():
while 1:
cust = (yield)
print "No such customer type '%s'" % cust.custtype
并将其添加到您的管道中:
pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer(UndefinedCustomer()))))
(一个终止的UndefinedCustomer处理程序也允许你删除&#39;如果没有来自你的协同程序的代码 - 除了终止符之外都会有继承符,终结符知道它是终结符并且会不要叫继任者。)
通过这些更改,我从测试中获得此输出:
Platinum Customer
Gold Customer
No such customer type 'undefined'
另外,为什么在HandleCustomer中捕获StopIteration?这段代码应该足够了:
def HandleCustomer(self):
self.pipeline.send(self)