如何异步启动多个Python脚本?现有脚本仅运行最后一个的问题排查
问题分析与解决方案
核心问题
- 变量名与函数名错误:代码里定义了
list = json.load(...),但后续用的是未定义的exchanges_list,会触发NameError;另外handler里调用的handle_socket是不存在的,应该是handle_script。 - exec字符串执行的隐患:循环生成调用字符串存进列表的方式不仅不安全,还容易因为延迟执行出现绑定异常。更关键的是,如果你的脚本函数是同步的,直接在async函数里exec会阻塞事件循环,根本做不到真正异步。
- 函数调用格式错误:原循环生成的
模块名.模块名()格式不符合逻辑——你导入的是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
相关产品推荐
相关产品推荐

