discord.py Bot无法启动:bot实例移至__name__判断块后on_ready不触发
故障根因
discord.py的Bot实例在初始化时,会默认绑定当前线程已存在的事件循环。你将bot实例定义在if __name__ == "__main__"代码块、asyncio.run()调用之前时,会触发时序问题:
bot = BotClient()执行时,当前线程还没有运行中的事件循环,Bot会自动创建一个新的事件循环绑定到自身- 后续调用
asyncio.run(main())时,该方法会销毁当前线程已存在的所有旧事件循环,重新创建一个全新的事件循环来运行main()协程 - 最终导致你的
bot实例绑定的是已经被销毁的旧循环,await bot.start()本质是挂在已失效的循环上执行,自然不会触发任何事件,程序只会空转阻塞。
修复方案
最稳妥的修复方式是避免用全局变量传递bot实例,直接将bot作为参数传入main()协程,修复后代码如下:
"""Entry Point""" import os import asyncio from app.core import BotClient # subclass of `discord.ext.commands.Bot` # 增加bot参数接收 async def main(bot: BotClient): try: await bot.start(os.getenv("BOT_TOKEN")) except KeyboardInterrupt: await bot.close() if __name__ == "__main__": try: bot = BotClient() # 传入bot实例 asyncio.run(main(bot)) except KeyboardInterrupt: pass
你也可以直接使用最初的正常写法,把bot实例的定义放回main()协程内部,避免事件循环绑定的时序问题。
内容的提问来源于stack exchange,提问作者user16013201
相关产品推荐
相关产品推荐

