Discord.py中在Cog类使用@bot.tree.command出现AttributeError的解决方法
解决Discord.py Cog中使用Slash命令的错误问题
错误原因
出现AttributeError: module 'discord.ext.commands' has no attribute 'tree'的核心原因是:tree是Bot实例的专属属性,不属于discord.ext.commands模块,不能直接用@commands.tree.command装饰器。同时主文件还存在实例引用错误和缺少命令同步的问题。
具体修改步骤
1. 修正Cog文件代码
推荐使用@app_commands.command()装饰器定义Slash命令,这是Cog中最规范的写法:
import discord from discord import app_commands from discord.ext import commands class SlashCommands(commands.Cog): def __init__(self, bot): self.bot = bot # 使用app_commands.command定义Slash命令,可指定名称和描述 @app_commands.command(name="hello", description="输入内容并发送消息") async def hello(self, interaction: discord.Interaction, thing_to_say: str): await interaction.response.send_message(f"{thing_to_say}") async def setup(bot): cog = SlashCommands(bot) await bot.add_cog(cog) # 将Cog中的命令注册到Bot的命令树 bot.tree.add_command(cog.hello)
2. 修正主文件代码
- 类内方法必须用
self引用当前Bot实例,不能直接调用全局变量bot - 使用
setup_hook替代on_ready处理扩展加载和命令同步(更稳定,避免重复触发) - 添加命令同步代码,否则Slash命令不会在Discord客户端显示
修改后的主文件:
import os import discord from dotenv import load_dotenv from discord.ext import commands, tasks extens = ["cogs.slash_commands"] class MyBot(commands.Bot): def __init__(self): # Slash命令不依赖前缀,可随意设置 super().__init__(command_prefix='!', intents=discord.Intents.all()) async def setup_hook(self): # 加载所有扩展 for cog in extens: try: await self.load_extension(cog) print(f"{cog} 加载成功") except Exception as e: print(f"加载{cog}失败: {str(e)}") # 同步全局Slash命令(全局同步需等待几分钟生效) await self.tree.sync() # 测试服务器可指定ID快速同步,替换成你的服务器ID # await self.tree.sync(guild=discord.Object(id=123456789012345678)) async def on_ready(self): print(f'{self.user} 已成功启动!') bot = MyBot() load_dotenv() bot.run(os.getenv('TOKEN'))
额外注意事项
- 确保Discord.py版本为2.0及以上,Slash命令仅在该版本后正式支持
- 全局命令同步后,Discord需要几分钟时间推送至所有服务器,测试环境建议用指定服务器ID同步,可立即生效
setup_hook是Discord.py 2.0新增的初始化方法,比on_ready更可靠(on_ready可能因Bot重连触发多次)
内容的提问来源于stack exchange,提问作者dohyunii
相关产品推荐
相关产品推荐

