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。
这样,异步编程的时候也可以正常使用迭代器了。