簡體   English   中英

我可以將列表傳遞給 asyncio.gather 嗎?

[英]Can I pass an list to asyncio.gather?

我正在嘗試使用forasyncio.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 gatherloop參數在 3.8 中已棄用,並將在 3.10 中刪除。 除非您使用的是舊版本的 Python,否則您可以刪除它並調用asyncio.get_event_loop

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM