如何修复discord.py中的Event Loop Closed Error问题
修复自定义Discord Bot类的"Runtime Error: Event loop is closed"问题
常见原因及对应修复方案
1. 错误重写了run方法
如果自定义类重写了run方法,却没正确处理事件循环的生命周期,就会触发这个错误。commands.Bot的run方法已经封装了事件循环的启动、运行和关闭逻辑,新手不要轻易修改它。
错误示例:
class MyBot(commands.Bot): def run(self, token): loop = asyncio.get_event_loop() loop.run_until_complete(self.start(token)) loop.close() # 手动关闭循环会打断后续内部清理任务
修复方案:
要么完全不重写run方法,直接调用父类的实现;如果必须扩展逻辑,要确保调用父类的run来处理循环:
class MyBot(commands.Bot): def run(self, token, *args, **kwargs): # 这里添加自定义前置逻辑 super().run(token, *args, **kwargs) # 交给父类处理循环生命周期 # 这里添加自定义后置逻辑(父类run结束后循环已正常关闭,不要手动再关)
2. 初始化时误操作事件循环
如果在自定义类的__init__方法里手动创建并关闭事件循环,会导致后续启动时循环已经处于关闭状态。
错误示例:
class MyBot(commands.Bot): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.loop.close() # 提前关闭了循环
修复方案:
不要在__init__里手动操作事件循环,commands.Bot会自动处理循环的创建和管理:
class MyBot(commands.Bot): def __init__(self, command_prefix, intents, *args, **kwargs): super().__init__(command_prefix=command_prefix, intents=intents, *args, **kwargs) # 在这里添加自定义属性或初始化逻辑,不要碰事件循环
3. 使用start后手动关闭循环
如果代码里不用bot.run(),而是用loop.run_until_complete(bot.start(token))后手动关闭循环,也会引发错误。因为bot.start()之后,Discord.py内部还有清理任务,手动关闭循环会打断这些任务。
错误示例:
async def main(): bot = MyBot(command_prefix="!", intents=intents) await bot.start("YOUR_TOKEN") loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close() # 手动关闭导致异常
修复方案:
新手推荐直接用bot.run("YOUR_TOKEN");如果要用异步主函数,使用asyncio.run()自动处理循环的创建和关闭:
async def main(): async with MyBot(command_prefix="!", intents=intents) as bot: await bot.start("YOUR_TOKEN") asyncio.run(main())
新手建议
- 尽量不要重写
commands.Bot的核心方法(如run、start),先熟悉父类的默认行为。 - 所有异步逻辑都放在
async函数里,不要混用同步和异步的事件循环操作。 - 确保
intents设置正确,错误的权限配置可能引发其他异常,间接导致循环异常关闭。
内容的提问来源于stack exchange,提问作者hridlow
相关产品推荐
相关产品推荐

