You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现无Asyncio的Python协程责任链循环?

问题分析与修复方案

核心问题

  1. 处理器逻辑错误:Handler_59的判断范围与Handler_04重复,未实现5-9区间的处理判断。
  2. 循环链初始化错误:无法直接构建闭环引用,导致最后一个处理器无法将数据送回第一个。
  3. 协程终止未处理:处理器return时会抛出StopIteration,直接send会触发异常。
  4. 可变默认参数问题:handler_chain的list=[]会导致多次调用时数据累积。

修复后的实现代码

import functools

def coroutine(function):
    @functools.wraps(function)
    def wrapper(*args, **kwargs):
        generator = function(*args, **kwargs)
        next(generator)
        return generator
    return wrapper

@coroutine
def Handler_04(successor):
    while True:
        num = yield
        if 0 <= num[0] <= 4:
            print(f"Handler_04 处理数据: {num}")
            # 处理完成,终止当前协程
            return
        else:
            try:
                successor.send(num)
            except StopIteration:
                # 后续协程终止,结束当前流程
                return

@coroutine
def Handler_59(successor):
    while True:
        num = yield
        if 5 <= num[0] <= 9:
            print(f"Handler_59 处理数据: {num}")
            return
        else:
            try:
                successor.send(num)
            except StopIteration:
                return

@coroutine
def Handler_gt9(successor):
    while True:
        num = yield
        print(f"Handler_gt9 处理数据: {num} → 修改为 [{num[0]-num[1]}, {num[1]}]")
        num[0] -= num[1]
        if num[0] < 0:
            print(f"数据 {num} 无法处理,终止流程")
            return
        try:
            # 修改后送回下一个处理器(即第一个处理器,形成循环)
            successor.send(num)
        except StopIteration:
            return

# 构建闭环责任链
# 先创建处理器,后续补全successor引用
first = Handler_04(None)
second = Handler_59(None)
third = Handler_gt9(first)  # 最后一个处理器的下一个是第一个,形成循环

# 补全前两个处理器的successor
first.gi_frame.f_locals['successor'] = second
second.gi_frame.f_locals['successor'] = third

def handler_chain(data_list=None):
    if data_list is None:
        data_list = []
    for num in data_list:
        # 复制列表避免原数据被修改
        num_copy = num.copy()
        try:
            first.send(num_copy)
        except StopIteration:
            continue

# 测试示例
if __name__ == "__main__":
    test_data = [[0,5], [5,7], [12,4], [20,6]]
    handler_chain(test_data)

关键说明

  • 闭环链构建:先创建所有处理器,再通过协程的gi_frame.f_locals修改内部的successor变量,实现Handler_04 → Handler_59 → Handler_gt9 → Handler_04的循环。
  • 逻辑修正:Handler_59改为判断5-9区间,每个处理器处理完成后return终止协程。
  • 异常处理:send时捕获StopIteration,避免后续协程终止时触发全局异常。
  • 数据保护:发送数据前复制列表,防止原输入数据被修改。
  • 默认参数修复:将list=[]改为data_list=None,避免可变默认参数的累积问题。

测试输出示例

Handler_04 处理数据: [0, 5]
Handler_59 处理数据: [5, 7]
Handler_gt9 处理数据: [12, 4] → 修改为 [8, 4]
Handler_59 处理数据: [8, 4]
Handler_gt9 处理数据: [20, 6] → 修改为 [14, 6]
Handler_gt9 处理数据: [14, 6] → 修改为 [8, 6]
Handler_59 处理数据: [8, 6]

内容的提问来源于stack exchange,提问作者Maridiama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:45:26