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

Discord机器人开发报错:'Button' object is not callable 求助

解决Discord机器人工单系统中的'Button' is not callable错误

问题详情

开发Discord机器人工单系统时触发以下错误:

TypeError: 'Button' object is not callable

原代码

class ticket_launcher(discord.ui.View):
    def __init__(self) -> None:
        super().__init__(timeout=None)
    
    @discord.ui.Button(label='Create a ticket', style = discord.ButtonStyle.blurple, custom_id = 'ticket_button')
    async def ticket(self, button: discord.ui.Button, interaction: discord.Interaction):
        ticket = discord.utils.get(interaction.guild.text_channels, name = f'ticket-for-{interaction.user.name}-{interaction.user.discriminator}')
        if ticket is not None: await interaction.response.send_message(f'You already have a ticket open at {ticket.mention}!', ephemeral = True)
        else:
            overwrites = {
                interaction.guild.default_role: discord.PermissionOverwrite(view_channel = False),
                interaction.user: discord.PermissionOverwrite(view_channel = True, send_messages = True, attach_files = True, embed_links = True),
                interaction.guild.me: discord.PermissionOverwrite(view_channel = True, send_messages = True, read_message_history = True)
            }
            channel = await interaction.guild.create_text_channel(name=f'ticket-for-{interaction.user.name}-{interaction.user.discriminator}', overwrites=overwrites, reason=f'Ticket for {interaction.user}.')
            await channel.send(f'{interaction.user.mention} created a ticket!')
            await interaction.response.send_message(f'I have opened a ticket for you at {channel.mention}.', ephemeral=True)

tree = app_commands.CommandTree(client=client)

@tree.command(guild = discord.Object(id=TICKET_CHANNEL), name='ticket', description='Launches the ticket system.')
async def ticket(interaction: discord.Interaction):
    embed = discord.Embed(title='If you have any problems click the big blue button below!', color=discord.Colour.blue())
    await interaction.channel.send(embed=embed, view=ticket_launcher())
    await interaction.response.send_message('Ticketing system has been launched successfully.', ephemeral=True)

错误回溯

Traceback (most recent call last):
  File "c:\Users\schul\Desktop\MORE PYTHON\bot.py", line 214, in <module>
    class ticket_launcher(discord.ui.View):
  File "c:\Users\schul\Desktop\MORE PYTHON\bot.py", line 219, in ticket_launcher
    async def ticket(self, button: discord.ui.Button, interaction: discord.Interaction):
TypeError: 'Button' object is not callable

解决方案

错误核心原因:按钮回调函数的名称与装饰器生成的Button实例重名。使用@discord.ui.Button装饰方法时,会在类中创建一个同名的Button对象,当方法名也是ticket时,会覆盖方法定义,导致后续解析时认为ticket是Button实例而非可调用方法。

修改步骤:

  • 将按钮回调函数的名称修改为不冲突的名字,比如create_ticket

修改后的代码

class ticket_launcher(discord.ui.View):
    def __init__(self) -> None:
        super().__init__(timeout=None)
    
    @discord.ui.Button(label='Create a ticket', style = discord.ButtonStyle.blurple, custom_id = 'ticket_button')
    async def create_ticket(self, button: discord.ui.Button, interaction: discord.Interaction):
        ticket = discord.utils.get(interaction.guild.text_channels, name = f'ticket-for-{interaction.user.name}-{interaction.user.discriminator}')
        if ticket is not None: 
            await interaction.response.send_message(f'You already have a ticket open at {ticket.mention}!', ephemeral = True)
        else:
            overwrites = {
                interaction.guild.default_role: discord.PermissionOverwrite(view_channel = False),
                interaction.user: discord.PermissionOverwrite(view_channel = True, send_messages = True, attach_files = True, embed_links = True),
                interaction.guild.me: discord.PermissionOverwrite(view_channel = True, send_messages = True, read_message_history = True)
            }
            channel = await interaction.guild.create_text_channel(name=f'ticket-for-{interaction.user.name}-{interaction.user.discriminator}', overwrites=overwrites, reason=f'Ticket for {interaction.user}.')
            await channel.send(f'{interaction.user.mention} created a ticket!')
            await interaction.response.send_message(f'I have opened a ticket for you at {channel.mention}.', ephemeral=True)

tree = app_commands.CommandTree(client=client)

@tree.command(guild = discord.Object(id=TICKET_CHANNEL), name='ticket', description='Launches the ticket system.')
async def ticket(interaction: discord.Interaction):
    embed = discord.Embed(title='If you have any problems click the big blue button below!', color=discord.Colour.blue())
    await interaction.channel.send(embed=embed, view=ticket_launcher())
    await interaction.response.send_message('Ticketing system has been launched successfully.', ephemeral=True)

内容的提问来源于stack exchange,提问作者ImCurrentlyLearningPython

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 21:55:20