You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将self.canCraft传入discord按钮装饰器?非全局变量方案

解决discord.ui.button装饰器无法使用实例变量设置disabled的问题

问题原因

你当前的写法无效,是因为装饰器在类定义阶段就会执行,此时类的实例还未创建,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:28:11