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

如何将异步可迭代对象转换为非列表可迭代对象并规避语法错误

将异步迭代器转换为流式同步可迭代对象

原代码(运行正常)

import asyncio
from collections.abc import AsyncIterable, Iterable


# 实际场景中逻辑更复杂
async def create_asynchronous_iterable() -> AsyncIterable[int]:
    for k in range(3):
        yield k


# 实际场景中逻辑更复杂
def do_something(it: Iterable[int]) -> None:
    for k in it:
        print(k, end=" ")
    print()


async def main():
    async_it = create_asynchronous_iterable()
    it = [k async for k in async_it]
    do_something(it)


if __name__ == "__main__":
    asyncio.run(main())  # 输出 "0 1 2 "

问题描述

当前代码会把异步迭代器的所有元素一次性加载到列表中再传入do_something,现在需要将it转换为无需预加载所有元素到内存的流式可迭代对象(比如生成器),避免大数量场景下的内存占用问题。

错误尝试及报错

尝试在同步生成器中直接使用async for,触发语法错误:

async def main():
    async_it = create_asynchronous_iterable()

    def create_iterable() -> Iterable[int]:
        async for k in async_it:
            yield k
    
    it = create_iterable()
    do_something(it)

报错信息:

SyntaxError: 'async for' outside async function

解决方案

核心思路是借助当前运行的事件循环,在同步生成器中逐个异步获取元素并返回,实现流式迭代。修改后的main函数如下:

async def main():
    async_it = create_asynchronous_iterable()
    loop = asyncio.get_running_loop()

    def create_iterable() -> Iterable[int]:
        # 把异步迭代器包装为异步生成器
        async def async_gen():
            async for item in async_it:
                yield item
        
        agen = async_gen()
        while True:
            try:
                # 通过事件循环阻塞获取下一个异步元素
                item = loop.run_until_complete(agen.__anext__())
                yield item
            except StopAsyncIteration:
                break

    it = create_iterable()
    do_something(it)

原理说明

  1. async for语法仅允许在异步函数/异步生成器中使用,因此先将原异步迭代器包装为异步生成器async_gen。
  2. 在同步生成器create_iterable中,通过当前事件循环的run_until_complete()方法,每次阻塞等待获取异步生成器的下一个元素,再通过同步生成器yield出去。
  3. 这种方式不会一次性加载所有元素到内存,而是在do_something迭代时才逐个拉取异步元素,实现流式处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 07:00:12