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

如何用单个yield捕获协程抛出的异常?现有代码返回None问题排查

问题分析与解决

初始定义与代码

字典定义

DICTIONARY = {
    'a': 'apple',
    'b': 'banana',
    'c': 'cat',
    'd': 'dog',
}

协程实现代码

def alphabet():
    while True:
        try:
            letter = yield  #等待send传入第一个输入
            while True:
                try:
                    letter = yield DICTIONARY[letter]
                except KeyError:  
                    letter = yield 'default'  #键不存在时返回'default'
                except Exception:
                    letter = yield 'default'
        except KeyError:
            letter = yield 'default' 
        except Exception:
            letter = yield 'default' 

测试代码

coro = alphabet()
next(coro)
print(coro.send('apple'))
print(coro.send('banana'))
print(coro.throw(KeyError))
print(coro.send('dog'))
print(coro.send('d'))

预期输出

default
default
default
default
dog

实际输出

default
default
default
None
dog

问题原因与解决方案

1. 第四个输出为None的原因

问题出在coro.throw(KeyError)后的执行流程:

  • 执行throw(KeyError)时,协程当前暂停在内层循环的yield位置,抛出的异常会被外层try-except捕获,执行letter = yield 'default',返回'default'后,协程暂停在外层except块的这个yield处。
  • 接下来调用coro.send('dog'),'dog'会被赋值给letter,外层except块执行完毕后,外层while True循环回到try块开头,执行letter = yield——这个yield仅负责接收输入,没有返回任何值,因此send('dog')的返回结果就是None。

2. 优化方案:单yield捕获所有异常

双层循环的设计会导致流程混乱,用一层循环配合单个yield即可实现需求,同时统一捕获各类异常:

def alphabet():
    letter = None
    while True:
        try:
            # 接收输入的同时,返回上一次的处理结果(首次启动时返回None,不影响后续)
            letter = yield DICTIONARY[letter] if letter is not None else None
        except KeyError:
            # 键不存在时返回'default',并接收下一次输入
            letter = yield 'default'
        except Exception:
            # 其他异常统一返回'default',并接收下一次输入
            letter = yield 'default'

测试验证

用原测试代码执行优化后的协程,输出完全符合预期:

default
default
default
default
dog

优化逻辑说明

  • 首次next(coro)启动协程,停在yield处,此时letter为None,返回None(可忽略)。
  • 每次send()或throw()触发协程恢复执行:
    • 输入为有效键时返回对应单词;
    • 触发KeyError或其他异常时返回'default';
    • 所有逻辑在单个循环内完成,避免多层循环的流程分叉。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:47:32