Python 异步迭代器 解决TypeError: ‘async_generator‘ object is not iterable

迭代器是生成器的一种,使用迭代器生成可迭代对象,可以避免创建巨大的列表或元组。

昨天DEBUG的时候,出现了一个BUG:TypeError: 'async_generator' object is not iterable,async_generator对象不可迭代

以下,是我的解决过程。

问题

)同步函数

代码

def generator():
    a = 1
    while a < 10:
        a += 1
        yield a


def main():
    print(type(generator()))
    res = list(generator())
    print(res)


if __name__ == '__main__':
    main()

输出:

<class 'generator'>
[2, 3, 4, 5, 6, 7, 8, 9, 10]

正常,没有问题。

)异步函数

import asyncio


async def agenerator():
    a = 1
    while a < 10:
        a += 1
        yield a


async def main():
	print(type(list(agenerator())))
    res = await list(agenerator())
    print(res)


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

TypeError: 'async_generator' object is not iterable
agenerator()和main()是个异步函数,返回的是个async_generator对象,此对象不可迭代。

那么如何解决这种问题呢?

解决方法

有一个aiostream库可以解决此类问题,它相当于是itertools的异步版本,pip install aiostream

这里仅介绍针对此问题的处理方法,其它详细内容请参考官网:https://aiostream.readthedocs.io/en/stable/

代码改写为:

from aiostream.stream import list as alist
import asyncio


async def agenerator():
    a = 1
    while a < 10:
        a += 1
        yield a


async def main():
    print(type(alist(agenerator())))
    res = await alist(agenerator())
    print(res)


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

输出:

<class 'aiostream.stream.aggregate.list'>
[2, 3, 4, 5, 6, 7, 8, 9, 10]

将line:13的list换成aiostream.stream.aggregate.list,为了避免混淆,将其命名为alist,相当于同步迭代器里的list。

这样,异步编程的时候也可以正常使用迭代器了。

posted @ 2022-04-06 14:44  王舰  阅读(5002)  评论(0编辑  收藏  举报