Discord Bot跨设备运行异常:Cog加载与事件循环错误排查
问题解决方案
核心问题分析
你的问题主要来自三个点:Discord.py版本差异导致的API用法混淆、Cog的setup函数写法错误、事件循环嵌套调用冲突。
1. 统一Discord.py版本
先确保树莓派上安装的Discord.py版本和本地开发环境一致,避免API差异:
# 先卸载现有版本 pip uninstall discord.py -y # 安装和本地相同的版本(比如v2.3.2,替换成你本地的版本号) pip install discord.py==2.3.2
2. 修正主程序代码
bot.run()本身会启动并阻塞事件循环,不能放在asyncio.run()调用的async函数里执行,否则会触发嵌套事件循环错误。正确的写法是先加载Cog,再启动Bot:
import discord from discord.ext import commands import os import asyncio from dotenv import load_dotenv load_dotenv() intents = discord.Intents().all() TOKEN = os.getenv('BOT_TOKEN') bot = commands.Bot(command_prefix="$", help_command=None, intents=intents, owner_ids={REDACTED}) async def load_cogs(): # 遍历Cog目录加载所有扩展 for file in os.listdir("./Cog"): if file.endswith(".py") and not file.startswith("_"): # 排除临时文件 try: await bot.load_extension(f"Cog.{file[:-3]}") print(f"成功加载Cog: {file[:-3]}") except Exception as e: print(f"加载Cog {file[:-3]}失败: {str(e)}") async def main(): await load_cogs() # 用start代替run,因为run会自己处理事件循环,start需要手动挂起 await bot.start(TOKEN) if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: # 捕获Ctrl+C,优雅退出 asyncio.run(bot.close())
3. 修正Cog文件的setup函数
Discord.py v2.x中,Cog的setup函数必须是同步函数,不能加async/await,这是你之前触发NoneType错误的核心原因。正确的Cog模板如下:
# Cog/example.py 示例Cog文件 from discord.ext import commands class ExampleCog(commands.Cog): def __init__(self, bot): self.bot = bot @commands.command() async def hello(self, ctx): await ctx.send("Hello from Example Cog!") # 必须是同步的setup函数 def setup(bot): bot.add_cog(ExampleCog(bot))
错误对应解释
- 未await
load_extension警告:Discord.py v2.x中load_extension改为了异步协程,必须用await调用,同步调用会触发警告且无法正确加载Cog。 - NoneType await错误:你把setup函数改成async后,Discord.py会尝试await它,但setup函数本身没有返回协程对象,导致触发类型错误。
- 事件循环嵌套错误:
bot.run()内部会调用asyncio.run()启动事件循环,你在自己的asyncio.run()里再调用bot.run(),就会导致嵌套事件循环冲突,改用bot.start()即可避免。
内容的提问来源于stack exchange,提问作者Magus
相关产品推荐
相关产品推荐

