Discord机器人运行报错:PyNaCl未安装及事件循环异常求助
问题分析
核心错误是RuntimeError: no running event loop,原因是你在EpicBot的__init__方法里直接调用了self.update_prefixes_db.start(),而discord.ext.tasks的start()方法需要在已运行的asyncio事件循环中执行,但此时Bot还未启动,事件循环尚未创建。
解决方案
方法1:将任务启动移到Bot就绪钩子中(推荐)
修改utils/bot.py,把启动定时任务的代码从__init__方法移到setup_hook内——这个方法会在Bot登录后、就绪前被调用,此时事件循环已正常运行:
class EpicBot(commands.Bot): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 移除原来的self.update_prefixes_db.start() async def setup_hook(self): self.update_prefixes_db.start()
如果习惯用on_ready事件,也可以这么写(注意加运行判断,避免重连时重复启动):
class EpicBot(commands.Bot): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) async def on_ready(self): if not self.update_prefixes_db.is_running(): self.update_prefixes_db.start()
方法2:手动维护事件循环(不推荐)
如果一定要在初始化阶段启动任务,需要手动创建并绑定事件循环,但这种方式不符合discord.py的规范,容易引发其他异步问题:
先修改main.py的启动逻辑:
import asyncio async def main(): client = EpicBot() await client.start("你的Bot令牌") if __name__ == "__main__": asyncio.run(main())
再调整utils/bot.py的__init__方法:
import asyncio class EpicBot(commands.Bot): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) loop = asyncio.get_event_loop() loop.create_task(self.update_prefixes_db.start())
额外提示
- PyNaCl的警告仅表示语音功能不可用,和当前报错无关,无需处理,若需要语音功能再执行
pip install pynacl即可。 - 未关闭的client_session问题会随着事件循环正常结束自动解决,无需单独处理。
内容的提问来源于stack exchange,提问作者Infinity A.B.S
相关产品推荐
相关产品推荐

