如何将self.canCraft传入discord按钮装饰器?非全局变量方案
问题原因
你当前的写法无效,是因为装饰器在类定义阶段就会执行,此时类的实例还未创建,self根本不存在,自然无法访问self.canCraft这个实例变量。
解决方案
不要在装饰器中直接引用实例变量,而是在类的__init__方法里修改按钮的disabled属性。具体实现有两种方式:
方式1:通过custom_id定位按钮(推荐)
给按钮添加唯一标识的custom_id,在初始化时精准定位并修改状态:
class CraftView(discord.ui.View): def __init__(self, viewOwner, craftItem, canCraft): super().__init__() self.viewOwner = viewOwner self.craftItem = craftItem self.canCraft = canCraft # 定位按钮并设置禁用状态 craft_button = self.get_item("craft_button") craft_button.disabled = self.canCraft @discord.ui.button( label="Craft", style=discord.ButtonStyle.primary, emoji="🔨", disabled=False, custom_id="craft_button" ) async def button_callback(self, interaction: discord.Interaction, button: discord.ui.Button): pass
方式2:遍历子元素查找按钮
如果不想用custom_id,可以遍历视图的子元素匹配按钮:
class CraftView(discord.ui.View): def __init__(self, viewOwner, craftItem, canCraft): super().__init__() self.viewOwner = viewOwner self.craftItem = craftItem self.canCraft = canCraft # 遍历子元素找到目标按钮 for item in self.children: if isinstance(item, discord.ui.Button) and item.label == "Craft": item.disabled = self.canCraft break @discord.ui.button(label="Craft", style=discord.ButtonStyle.primary, emoji="🔨", disabled=False) async def button_callback(self, interaction: discord.Interaction, button: discord.ui.Button): pass
原理说明
类实例化时,__init__方法会在装饰器执行之后运行,此时实例变量self.canCraft已经完成赋值,我们可以直接修改已创建的按钮对象的disabled属性,既实现了用实例变量控制按钮状态的需求,也完全不需要依赖全局变量。
内容的提问来源于stack exchange,提问作者JoJjjo157
相关产品推荐
相关产品推荐

