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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:05:08