Discord.py类间变量传递问题:按钮类调用Cog变量报错解决
Discord机器人代词确认按钮问题修复方案
问题描述
要实现用户输入代词后的确认验证系统,尝试将pronounCmd(commands.Cog子类)中pronoun方法的代词变量传递给PronounsView按钮类,但点击按钮时触发TypeError(缺少bot参数),且无法获取之前输入的代词值。
报错原因
- 实例化Cog参数缺失:按钮回调里直接调用
pronounCmd()创建新实例,但pronounCmd的构造函数要求传入bot参数,触发参数缺失错误。 - 数据不共享:就算传入
bot参数,新创建的pronounCmd实例和执行命令时的实例不是同一个,根本拿不到之前用户输入的代词值。
修复方案
不需要通过重新实例化Cog来获取数据,直接将代词值传递给PronounsView实例,让视图自己保存临时数据:
- 修改
PronounsView的构造函数,添加参数接收代词并保存为实例变量 - 在命令逻辑中创建
PronounsView时,传入用户输入的代词 - 按钮回调直接从当前View实例中读取保存的代词
完整修复代码
class pronounCmd(commands.Cog): def __init__(self, bot: commands.Bot): self.client = bot @app_commands.command(name="pronoun", description="Give yourself a custom role based on pronouns of your choosing.") async def pronoun(self, interaction: discord.Interaction, pronoun_1: str, pronoun_2: str): input_pronouns = f'{pronoun_1}/{pronoun_2}' embed = discord.Embed(title="You have chosen the following pronouns to give yourself!", description="", color=0x32a852) embed.add_field(name=input_pronouns, value="", inline=False) embed.add_field(name="Are you sure you want these pronouns as your role? You can always change it later.", value="", inline=False) # 创建视图时传入用户输入的代词 await interaction.response.send_message(embed=embed, view=PronounsView(input_pronouns)) # 确认按钮视图类 class PronounsView(discord.ui.View): def __init__(self, pronouns: str): super().__init__() self.pronouns = pronouns # 将代词保存到视图实例中 @discord.ui.button(label="Yes", style=discord.ButtonStyle.green) async def YesButton(self, interaction: discord.Interaction, button: discord.ui.Button): # 直接从当前视图实例读取代词 await interaction.response.send_message(f'已确认你的代词:{self.pronouns}')
额外优化建议
- 避免用Cog的实例变量存储临时请求数据,多用户同时触发命令时会互相覆盖,用局部变量传递更安全。
- 可以给
PronounsView添加超时配置(比如super().__init__(timeout=60)),超时后按钮自动失效,避免无效操作。
内容的提问来源于stack exchange,提问作者AlberTheWarlock
相关产品推荐
相关产品推荐

