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

如何更优雅地获取接收yield值的Python生成器返回值?

获取接收值的生成器返回值的替代方法

首先明确:我们讨论的是通过yield接收外部传入值的生成器,这类生成器和仅产出值的普通生成器逻辑不同。

原代码示例

生成器函数通过yield接收外部值,累积后返回结果:

def gen():
    accumulator = []
    # 循环接收传入值,直到收到None
    while (incoming := (yield)) is not None:
        accumulator.append(incoming)
    return accumulator

原调用方式(需捕获StopIteration获取返回值):

dataset = [1, 2, 3, 4]
g = gen()
next(g)  # 预激生成器,使其进入接收状态

for item in dataset:
    g.send(item)

# 发送None终止生成器,捕获异常获取返回值
try:
    g.send(None)
except StopIteration as e:
    result = e.value

print(result)  # 输出: [1, 2, 3, 4]

更优雅的替代方法

方法1:利用yield from自动捕获返回值

Python 3.3+ 引入的yield from语法会自动处理生成器的StopIteration异常,并将返回值作为表达式结果返回。我们可以封装一个辅助函数来简化逻辑:

def run_accumulator_gen(gen_func, dataset):
    g = gen_func()
    next(g)  # 预激生成器
    try:
        # 发送所有数据到生成器
        for item in dataset:
            g.send(item)
        # 通过yield from获取生成器返回值
        return (yield from g)
    finally:
        g.close()  # 确保生成器正确关闭

# 调用示例
dataset = [1, 2, 3, 4]
# 包装为生成器执行以触发yield from
def get_result():
    return (yield from run_accumulator_gen(gen, dataset))

result = next(get_result())
print(result)  # 输出: [1, 2, 3, 4]

方法2:简化异常捕获逻辑

如果不想引入额外辅助函数,可以简化原有的异常捕获代码,使其更紧凑:

dataset = [1, 2, 3, 4]
g = gen()
next(g)

# 批量发送数据
for item in dataset:
    g.send(item)

# 紧凑捕获返回值
result = None
try:
    g.send(None)
except StopIteration as e:
    result = e.value

print(result)  # 输出: [1, 2, 3, 4]

说明

  • 预激生成器的步骤(next(g))不可省略:生成器刚实例化时处于初始暂停状态,必须通过next()或g.send(None)启动,才能进入接收外部值的状态。
  • yield from是官方推荐的处理生成器协作与返回值的方式,在复杂逻辑场景下可读性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:21:11