Python 责任链和协程

Python Chain of Responsibility and coroutine

提问人:Alex 提问时间:10/27/2023 更新时间:10/27/2023 访问量:22

问:

对不起,如果我写了一些愚蠢的东西,但我正在尝试解决一个关于考试的责任链和协程的练习。

以下是我的代码:

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 分钟给我建议的人。

Python 协程

评论


答:

1赞 Tim Roberts 10/27/2023 #1

这是因为你以错误的顺序做事,正如一些调试打印所显示的那样。由于您构建链的方式,首先被放入链中,因此您的请求从 04 到 59 到 gt9 再到 Default。在 gt9 修改请求后,没有人知道如何处理该结果。在每个之后添加 (etc) 以查看其实际效果。DefaultHandlerprint('04:',request)request = yield

如果我颠倒客户端中处理程序的顺序,它会按您的预期工作。