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

如何实现上下文管理器/生成器多次yield以收集批量处理的多异常?

列表批量处理异常的解决方案

问题背景

需要遍历列表处理元素时,收集每个触发异常的元素错误信息,而非遇到第一个异常就终止流程。尝试过三种方式但都有问题:

  • 上下文管理器:因@contextmanager仅允许一次yield,无法循环输出元素实现逐个处理
  • 生成器迭代:yield出元素后,处理代码在生成器外部执行,异常无法被生成器内的except捕获,会直接终止循环
  • 函数封装:可行,但需要显式定义处理函数,希望有更简洁的调用方式,想把代码块当作可多次执行的函数使用

可行解决方案

方案1:用Lambda简化函数传递

无需显式定义命名函数,用匿名函数直接传入处理逻辑,写法紧凑:

class MultipleExceptions(Exception):
    def __init__(self, errors):
        self.errors = errors
        super().__init__(f"共遇到 {len(errors)} 个错误: {errors}")

    @staticmethod
    def test_items(items, handler):
        errors = []
        for idx, value in enumerate(items):
            try:
                handler(value)
            except Exception as e:
                errors.append((idx, value, str(e)))
        if errors:
            raise MultipleExceptions(errors)

# 调用示例
items = [1,2,3,4,5]
MultipleExceptions.test_items(items, lambda val:
    # 这里编写你的处理逻辑
    print(f"正在处理 {val}")
    if val == 3:
        raise Exception("3 err")
    if val == 5:
        raise Exception("5 err")
)

方案2:自定义迭代器适配for循环习惯

如果更偏好for循环的写法,可以实现一个自定义迭代器,在迭代过程中捕获异常:

class MultipleExceptions(Exception):
    def __init__(self, errors):
        self.errors = errors
        super().__init__(f"共遇到 {len(errors)} 个错误: {errors}")

class ExceptionCatcher:
    def __init__(self, items):
        self.items = items
        self.errors = []

    def process(self, handler):
        for idx, value in enumerate(self.items):
            try:
                handler(value)
            except Exception as e:
                self.errors.append((idx, value, str(e)))
        if self.errors:
            raise MultipleExceptions(self.errors)

# 调用示例
items = [1,2,3,4,5]
ExceptionCatcher(items).process(lambda val:
    # 处理逻辑
    print(f"正在处理 {val}")
    if val == 3:
        raise Exception("3 err")
    if val == 5:
        raise Exception("5 err")
)

关于代码块转可多次执行函数的说明

Python无法直接将一段代码块(如with块内的代码)当作可重复调用的函数,除非将其封装为函数、Lambda,或使用exec/eval(不推荐,存在安全风险且维护性差)。上述Lambda方案已经是兼顾简洁性与功能的最优选择,无需显式定义命名函数即可实现需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:13:10