[英]Can I pass an list to asyncio.gather?
I am trying to start a bunch (one or more) aioserial instances using an for
and asyncio.gather
without success.我正在尝试使用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())
I based this on the asyncio documentation example and some answers from stack overflow.我基于 asyncio 文档示例和堆栈溢出的一些答案。 But when I try to run it, I just got errors:但是当我尝试运行它时,我得到了错误:
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
I also tried to use a set instead of a list, but nothing really changed.我也尝试使用集合而不是列表,但没有真正改变。 Is there a better way to start a bunch of parallels corotines when you need to use a loop?当您需要使用循环时,是否有更好的方法来启动一堆并行 corotines? Thanks for the attention.感谢您的关注。
Your problem isn't with how you call gather
.您的问题不在于您如何调用gather
。 It's with how you define main
.这与您定义main
的方式有关。 The clue is with the error message线索是错误消息
ValueError: a coroutine was expected, got None
and the last line of code in the traceback before the except is raised以及引发异常之前的回溯中的最后一行代码
asyncio.run(main())
asyncio.run
wants an awaitable. asyncio.run
想要一个可等待的。 You pass it the return value of main
, but main
doesn't return anything.您将main
的返回值传递给它,但main
不返回任何内容。 Rather than adding a return value, though, the fix is to change how you define main
.但是,解决方法是更改您定义main
的方式,而不是添加返回值。
async def main():
This will turn main
from a regular function to a coroutine
that can be awaited.这会将main
从常规的 function 变为可以等待的coroutine
。
Edit编辑
Once you've done this, you'll notice that gather
doesn't actually seem to do anything.完成此操作后,您会注意到gather
实际上似乎没有做任何事情。 You'll need to await it in order for main
to wait for everything in lst_coro
to complete.您需要等待它,以便main
等待lst_coro
中的所有内容完成。
await asyncio.gather(*lst_coro)
Unrelated to your error: you shouldn't need to use loop
inside main
at all.与您的错误无关:您根本不需要在main
中使用loop
。 gather
's loop
argument was deprecated in 3.8 and will be removed in 3.10. gather
的loop
参数在 3.8 中已弃用,并将在 3.10 中删除。 Unless you're using an older version of Python, you can remove it and your call to asyncio.get_event_loop
.除非您使用的是旧版本的 Python,否则您可以删除它并调用asyncio.get_event_loop
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.