You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将列表传入asyncio.gather?如何用循环批量启动并行协程

问题原因

你遇到的报错是几个基础用法错误导致的:

  1. main是普通同步函数,没有用async关键字声明,调用后返回None,但asyncio.run()要求传入协程对象,这是报错的直接诱因。
  2. asyncio.gather()本身是协程函数,必须用await调用才会执行内部的协程任务,你原代码仅调用了gather没有等待执行,就算解决第一个问题也不会跑串口任务。
  3. 额外冗余/隐患:Python 3.7+ 用asyncio.run()时不需要手动获取事件循环,gather的loop参数已在高版本弃用;另外你循环里的未知协议分支没有跳过后续逻辑,遇到未知协议会触发类型错误。

修正后的代码

# -*- coding: utf-8 -*-
import asyncio
import aioserial
from protocol import contactid, ademco
# 补充原代码缺失的导入
import utils
import log

async def main():
    centrals = utils.auth()
    lst_coro = []
    for central in centrals:
        protocol = central['protocol']
        id = central['id']
        name = central['name']
        port = central['port']
        logger = log.create_logging_system(name)
        # 匹配协议处理函数
        if protocol == 'contactid':
            process_func = contactid.process
        elif protocol == 'ademco':
            process_func = ademco.process
        else:
            print(f'Unknown protocol: {protocol}')
            continue # 未知协议跳过后续逻辑
        # 解析串口参数
        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(process_func(aioserial_instance, id, name, logger))
    # 等待所有协程执行完成
    await asyncio.gather(*lst_coro)

if __name__ == '__main__':
    asyncio.run(main())

批量启动协程的最优方式

你原方案用列表存储循环生成的协程是官方推荐的标准写法,完全不需要换成集合:

  • 如果需要捕获单个协程的异常不影响其他任务,可以给gather加return_exceptions=True参数
  • 如果需要动态添加/取消任务,可以用asyncio.create_task()把协程包装成任务对象再存入列表,后续可以单独控制每个任务的生命周期

内容的提问来源于stack exchange,提问作者Guilherme Richter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 01:06:02