Discord.py v2自定义Help Command Cog加载失败问题求助
问题原因
你的HelpCommand类继承自commands.HelpCommand而非commands.Cog,却使用了仅适用于Cog的@commands.Cog.listener()装饰器,同时discord.py v2对扩展(Cog)的校验更严格,要求扩展必须是commands.Cog子类或通过合法的setup函数配置,这直接导致该模块无法被正常加载。
解决方案
有两种可行的修正方式,任选其一即可:
方式1:调整HelpCommand结构,移除Cog相关装饰器
修改HelpCommand.py代码,移除无效的listener装饰器,并将加载提示移至setup函数中:
import discord from discord.ext import commands class CustomHelpCommand(commands.HelpCommand): colour = 0x0dd2ff def footer(self): return f"{self.clean_prefix}{self.invoked_with} [command] for more information" def get_command_signature(self, command): return f"```\{self.clean_prefix}{command.qualified_name} {command.signature}```" async def send_cog_help(self, cog): embed = discord.Embed(title=f"**{cog.qualified_name}** commands", colour=self.colour) if cog.description: embed.description = cog.description filtered = await self.filter_commands(cog.get_commands(), sort=True) for command in filtered: embed.add_field(name=command.qualified_name, value=command.short_doc or "No description") embed.set_footer(text=self.footer()) await self.get_destination().send(embed=embed) async def send_command_help(self, command): embed = discord.Embed(title=command.qualified_name, colour=self.colour) if command.help: embed.description = command.help embed.add_field(name="Signature", value=self.get_command_signature(command)) embed.set_footer(text=self.footer()) await self.get_destination().send(embed=embed) async def send_bot_help(self, mapping): embed = discord.Embed(title="Bot Commands", colour=self.colour) description = self.context.bot.description if description: embed.description = description for cog, commands_list in mapping.items(): if not cog: continue filtered = await self.filter_commands(commands_list, sort=True) if filtered: # 仅显示用户有权限访问的命令 value = "\t".join(f"`{i.name}`" for i in filtered) embed.add_field(name=cog.qualified_name, value=value) embed.set_footer(text=self.footer()) await self.get_destination().send(embed=embed) async def setup(bot): bot.help_command = CustomHelpCommand() print("Cog loaded - HelpCommand.py")
方式2:将HelpCommand包装入Cog类(更规范)
把自定义HelpCommand封装到Cog中,符合discord.py v2的扩展规范,同时支持卸载时恢复原help命令:
import discord from discord.ext import commands class HelpCog(commands.Cog): def __init__(self, bot): self.bot = bot # 保存原help命令,卸载时恢复 self._original_help = bot.help_command bot.help_command = CustomHelpCommand() bot.help_command.cog = self def cog_unload(self): self.bot.help_command = self._original_help class CustomHelpCommand(commands.HelpCommand): colour = 0x0dd2ff def footer(self): return f"{self.clean_prefix}{self.invoked_with} [command] for more information" def get_command_signature(self, command): return f"```\{self.clean_prefix}{command.qualified_name} {command.signature}```" async def send_cog_help(self, cog): embed = discord.Embed(title=f"**{cog.qualified_name}** commands", colour=self.colour) if cog.description: embed.description = cog.description filtered = await self.filter_commands(cog.get_commands(), sort=True) for command in filtered: embed.add_field(name=command.qualified_name, value=command.short_doc or "No description") embed.set_footer(text=self.footer()) await self.get_destination().send(embed=embed) async def send_command_help(self, command): embed = discord.Embed(title=command.qualified_name, colour=self.colour) if command.help: embed.description = command.help embed.add_field(name="Signature", value=self.get_command_signature(command)) embed.set_footer(text=self.footer()) await self.get_destination().send(embed=embed) async def send_bot_help(self, mapping): embed = discord.Embed(title="Bot Commands", colour=self.colour) description = self.context.bot.description if description: embed.description = description for cog, commands_list in mapping.items(): if not cog: continue filtered = await self.filter_commands(commands_list, sort=True) if filtered: value = "\t".join(f"`{i.name}`" for i in filtered) embed.add_field(name=cog.qualified_name, value=value) embed.set_footer(text=self.footer()) await self.get_destination().send(embed=embed) async def setup(bot): await bot.add_cog(HelpCog(bot)) print("Cog loaded - HelpCommand.py")
额外说明
- 两种方式都能解决加载问题,方式2更符合discord.py v2的设计规范,支持Cog的卸载逻辑;
- 修正了
send_bot_help方法中使用未过滤命令的问题,确保只显示用户有权限访问的命令; - 原代码中的
@commands.Cog.listener()装饰器是无效的,因为commands.HelpCommand不是Cog子类,无法监听事件,加载提示直接放在setup函数中即可。
内容的提问来源于stack exchange,提问作者Sierra
相关产品推荐
相关产品推荐

