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

如何异步启动多个Python脚本?现有脚本仅运行最后一个的问题排查

问题分析与解决方案

核心问题

  1. 变量名与函数名错误:代码里定义了list = json.load(...),但后续用的是未定义的exchanges_list,会触发NameError;另外handler里调用的handle_socket是不存在的,应该是handle_script。
  2. exec字符串执行的隐患:循环生成调用字符串存进列表的方式不仅不安全,还容易因为延迟执行出现绑定异常。更关键的是,如果你的脚本函数是同步的,直接在async函数里exec会阻塞事件循环,根本做不到真正异步。
  3. 函数调用格式错误:原循环生成的模块名.模块名()格式不符合逻辑——你导入的是firstscript模块,应该调用模块里的具体函数(比如firstscript.main()),而不是模块本身的同名调用。

修正后的代码

假设你的list.json结构如下:

{
  "e": [["Firstscript"], ["Secondscript"]]
}

修正代码:

import json
import asyncio
import firstscript
import secondscript

def main():
    # 修正命名,规范文件读取方式
    with open('list.json') as f:
        exchanges_data = json.load(f)
    
    # 用字典映射模块名和对应入口函数,彻底替代exec
    script_map = {
        "firstscript": firstscript.main,  # 假设每个模块的入口函数是main
        "secondscript": secondscript.main
    }

    async def run_script(func):
        # 同步函数用asyncio.to_thread包装,避免阻塞事件循环
        await asyncio.to_thread(func)
    
    async def handler():
        tasks = []
        for item in exchanges_data['e']:
            exchange_name = item[0].lower()
            func = script_map.get(exchange_name)
            if func:
                tasks.append(run_script(func))
        # 批量等待所有异步任务完成
        await asyncio.gather(*tasks)
    
    asyncio.run(handler())

if __name__ == "__main__":
    main()

关键改进点

  • 移除exec,改用模块映射:通过字典直接关联模块名与函数,安全且易维护,彻底避免字符串执行的潜在问题。
  • 同步函数异步化处理:如果你的脚本函数是同步的,用asyncio.to_thread把它放到线程池执行,不阻塞事件循环,实现真正的异步并行。
  • 修正命名错误:解决原代码中的变量名、函数名错误,消除运行时异常。
  • 使用asyncio.gather:替代asyncio.wait,语法更简洁,更适合批量管理异步任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:55:13