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

Python:除async for外,从async函数的yield获取返回值的其他方法?

异步生成器的取值方法说明

先给你说结论:你贴的示例1和示例2完全用不了,不仅拿不到值还会直接报错。

为啥不行?因为async def搭配yield定义的是异步生成器,它和普通同步生成器的迭代逻辑完全不同:

  • 普通生成器用next()或者__next__()就能触发迭代,是同步操作
  • 异步生成器必须用专门的异步迭代方法__anext__(),而且必须搭配await才能拿到结果

正确的手动逐个取值方式

要是想手动挨个拿yield的值,得这么写:

import asyncio

async def test():
    yield "One"
    yield "Two"
    yield "Three"

async def call_test():
    x = test()
    print(await x.__anext__())  # 输出 One
    print(await x.__anext__())  # 输出 Two
    print(await x.__anext__())  # 输出 Three
    # 要是生成器已经没值了,再调用__anext__会抛出StopAsyncIteration异常

asyncio.run(call_test())

其他可行的取值方法

除了async for和上面这种手动调用的方式,还有几种实用的玩法:

  1. 异步列表推导式
    一次性把所有yield的值收集到列表里,省事高效:
async def call_test():
    results = [item async for item in test()]
    print(results)  # 输出 ['One', 'Two', 'Three']
  1. 批量异步处理(适合需要并发操作的场景)
    如果每个yield出来的值需要单独做异步处理,可以用asyncio.gather配合:
async def process_item(item):
    # 这里可以加自定义异步处理逻辑,比如调用其他async函数
    return item

async def call_test():
    gen = test()
    tasks = []
    try:
        while True:
            item = await gen.__anext__()
            tasks.append(asyncio.create_task(process_item(item)))
    except StopAsyncIteration:
        # 生成器耗尽时会触发这个异常,跳出循环
        pass
    results = await asyncio.gather(*tasks)
    print(results)  # 输出 ['One', 'Two', 'Three']

补充:示例1、2为啥报错?

运行示例1的代码时,会直接弹出TypeError: 'async_generator' object is not an iterator——因为异步生成器根本没实现同步迭代器的__next__()方法,next()函数也处理不了异步生成器对象,自然拿不到值。

内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:10:52