提问人:Alex 提问时间:10/27/2023 更新时间:10/27/2023 访问量:22
Python 责任链和协程
Python Chain of Responsibility and coroutine
问:
对不起,如果我写了一些愚蠢的东西,但我正在尝试解决一个关于考试的责任链和协程的练习。
以下是我的代码:
import functools
def coroutine(function):
@functools.wraps(function)
def wrapper(*args, **kwargs):
generator = function(*args, **kwargs)
next(generator)
return generator
return wrapper
@coroutine
def DefaultHandler(successor=None):
while True:
request = yield
if any(isinstance(x, str) for x in request) or request[0] < 0 or len(request) != 2:
print(f"Request {request} handled by Default_Handler: it was not possible to handle the request {request}")
else:
if successor is not None:
successor.send(request)
@coroutine
def Handler_04(successor=None):
while True:
request = yield
if isinstance(request[0], (int, float)) and 0 <= request[0] <= 4 and len(request) == 2:
print(f"Request {request} handled by Handler_04")
else:
if successor is not None:
successor.send(request)
@coroutine
def Handler_59(successor=None):
while True:
request = yield
if isinstance(request[0], (int, float)) and 5 <= request[0] <= 9 and len(request) == 2:
print(f"Request {request} handled by Handler_59")
else:
if successor is not None:
successor.send(request)
@coroutine
def Handler_gt9(successor=None):
while True:
request = yield
if isinstance(request[0], (int, float)) and request[0] > 9 and len(request) == 2:
print(
f"Message from Handler_gt9: it was not possible to handle the request {request}. Request modified")
new_data = [request[0] - request[1], request[1]]
if successor is not None:
successor.send(new_data)
else:
if successor is not None:
successor.send(request)
class Client:
def __init__(self):
self.handler = Handler_04(Handler_59(Handler_gt9(DefaultHandler(None))))
def delegate(self, requests):
for request in requests:
self.handler.send(request)
# Create a client object
client = Client()
# Create richieste to be processed.
requests = []
for i in range(0, 15, 2):
requests.append([i, 7])
requests.append([-3, 4])
requests.append(["a", 2])
requests.append([1, 2, 4])
client.delegate(requests)
现在,程序应该打印以下内容:
Request [0, 7] handled by Handler_04
Request [2, 7] handled by Handler_04
Request [4, 7] handled by Handler_04
Request [6, 7] handled by Handler_59
Request [8, 7] handled by Handler_59
Message from Handler_gt9: The request could not be handled [10, 7]. Request modified
Request [3, 7] handled by Handler_04
Message from Handler_gt9: The request could not be handled [12, 7]. Request modified
Request [5, 7] handled by Handler_59
Message from Handler_gt9: The request could not be handled [14, 7]. Request modified
Request [7, 7] handled by Handler_59
Request [-3, 4] handled by Default_Handler: request [-3, 4] could not be handled
Request ['a', 2] handled by Default_Handler: Request ['a', 2] could not be handled
Request [1, 2, 4] handled by Default_Handler: request [1, 2, 4] could not be handled
但是,当我走到这一步时
"Message from Handler_gt9: The request could not be handled [10, 7]. Request modified"
我的程序忽略了在 Handler_gt9中创建的新列表并继续,而我希望根据列表的值将新列表传递给正确的处理程序,在第一种情况下,列表变为 [3,7],应该由 Handler_04 管理(相反,我认为它被发送到 Defalut_Handler 然而,它什么都不做,因为它只需要处理有字符串或第一个负数)
我想了解的是我做错了什么,请记住,Client 类中的所有代码都是在练习中提供给我的,不应修改
感谢任何愿意浪费 10-15 分钟给我建议的人。
答:
1赞
Tim Roberts
10/27/2023
#1
这是因为你以错误的顺序做事,正如一些调试打印所显示的那样。由于您构建链的方式,首先被放入链中,因此您的请求从 04 到 59 到 gt9 再到 Default。在 gt9 修改请求后,没有人知道如何处理该结果。在每个之后添加 (etc) 以查看其实际效果。DefaultHandler
print('04:',request)
request = yield
如果我颠倒客户端中处理程序的顺序,它会按您的预期工作。
上一个:Quarkus 默认协程上下文
评论