迭代器是生成器的一種,使用迭代器生成可迭代對象,可以避免創建巨大的列表或元組。
昨天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。
這樣,異步編程的時候也可以正常使用迭代器了。