[英]Can I pass an list to asyncio.gather?
我正在嘗試使用for
和asyncio.gather
啟動一堆(一個或多個)aioserial 實例,但沒有成功。
# -*- coding: utf-8 -*-
import asyncio
import aioserial
from protocol import contactid, ademco
def main():
# Loop Asyncio
loop = asyncio.get_event_loop()
centrals = utils.auth()
# List of corotines to be executed in paralel
lst_coro = []
# Unpack centrals
for central in centrals:
protocol = central['protocol']
id = central['id']
name = central['name']
port = central['port']
logger = log.create_logging_system(name)
# Protocols
if protocol == 'contactid':
central = contactid.process
elif protocol == 'ademco':
central = ademco.process
else:
print(f'Unknown protocol: {central["protocol"]}')
# Serial (port ex: ttyUSB0/2400)
dev = ''.join(['/dev/', *filter(str.isalnum, port.split('/')[0])])
bps = int(port.split('/')[-1])
aioserial_instance = aioserial.AioSerial(port=dev, baudrate=bps)
lst_coro.append(central(aioserial_instance, id, name, logger))
asyncio.gather(*lst_coro, loop=loop)
if __name__ == '__main__':
asyncio.run(main())
我基於 asyncio 文檔示例和堆棧溢出的一些答案。 但是當我嘗試運行它時,我得到了錯誤:
Traceback (most recent call last):
File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/opt/Serial/serial.py", line 39, in <module>
asyncio.run(main())
File "/usr/lib/python3.7/asyncio/runners.py", line 37, in run
raise ValueError("a coroutine was expected, got {!r}".format(main))
ValueError: a coroutine was expected, got None
我也嘗試使用集合而不是列表,但沒有真正改變。 當您需要使用循環時,是否有更好的方法來啟動一堆並行 corotines? 感謝您的關注。
您的問題不在於您如何調用gather
。 這與您定義main
的方式有關。 線索是錯誤消息
ValueError: a coroutine was expected, got None
以及引發異常之前的回溯中的最后一行代碼
asyncio.run(main())
asyncio.run
想要一個可等待的。 您將main
的返回值傳遞給它,但main
不返回任何內容。 但是,解決方法是更改您定義main
的方式,而不是添加返回值。
async def main():
這會將main
從常規的 function 變為可以等待的coroutine
。
編輯
完成此操作后,您會注意到gather
實際上似乎沒有做任何事情。 您需要等待它,以便main
等待lst_coro
中的所有內容完成。
await asyncio.gather(*lst_coro)
與您的錯誤無關:您根本不需要在main
中使用loop
。 gather
的loop
參數在 3.8 中已棄用,並將在 3.10 中刪除。 除非您使用的是舊版本的 Python,否則您可以刪除它並調用asyncio.get_event_loop
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.