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

Pycord开发RulesButton角色按钮触发TypeError报错求助

问题根因

你遇到的两个TypeError分别来自两个基础用法错误:

  • 第一个报错:RulesButton.__init__() takes 1 positional argument but 2 were given
    你定义RulesButton类的构造函数时只声明了self一个入参,但实例化时传入了self.bot/self(Cog实例),参数数量不匹配。
  • 第二个报错:expected an instance of View not <class 'cogs.rules.RulesButton'>
    Pycord的add_view()方法仅接受View子类/实例作为入参,Button是UI组件不能单独作为视图注册,必须挂载到View容器中才能注册持久化监听。

另外原代码还有一个逻辑隐患:注册持久化视图时必须设置timeout=None,否则视图超时后会停止监听按钮点击;原代码中role is None分支没有任何反馈,用户点击后会出现无响应的情况。

修复方案
  1. 移除实例化RulesButton时多余的传参,当前按钮回调逻辑不需要调用bot实例,无需额外传入参数
  2. 持久化视图注册时,先创建timeout=None的View实例,将按钮添加到View中后再传入add_view()
  3. 确保发送规则消息和注册持久化视图时,按钮的custom_id完全一致
修正后完整代码
import discord
from discord.ext import commands
from discord.ui import *
from discord.ext.commands import Cog
from botconfig.rules import *
from botconfig.phrases import *

class RulesButton(discord.ui.Button):
    def __init__(self):
        super().__init__(
            label="Accept the Rules here!",
            style=discord.enums.ButtonStyle.green,
            custom_id="interaction:RoleButton",
        )
    async def callback(self, interaction: discord.Interaction):
        user = interaction.user
        role = interaction.guild.get_role(rules_id)

        if role is None:
            await interaction.response.send_message("❌ 角色配置异常,请联系管理员", ephemeral=True)
            return

        if role not in user.roles:
            await user.add_roles(role)
            await interaction.response.send_message("🎉 You accepted the Rules!", ephemeral=True)
        else:
            await interaction.response.send_message("❌ You already accepted the Rules!", ephemeral=True)

class Rules(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.is_owner()
    @commands.command()
    async def rules(self, ctx: commands.Context):
        if isinstance(ctx.channel, discord.DMChannel):
            return
        view = discord.ui.View(timeout=None)
        # 移除多余的self.bot传参
        view.add_item(RulesButton())
        await ctx.send(f"{RULES_BILD_URL}")
        await ctx.send(f"{RULES_BESCHREIBUNG}", view=view)

    @commands.Cog.listener()
    async def on_ready(self):
        # 持久化视图注册需要传入View实例,不能直接传Button
        persistent_view = discord.ui.View(timeout=None)
        persistent_view.add_item(RulesButton())
        self.bot.add_view(persistent_view)

def setup(bot):
    bot.add_cog(Rules(bot))
扩展说明

如果后续需要在按钮回调中调用bot实例,可以给RulesButton的__init__添加bot入参,示例如下:

class RulesButton(discord.ui.Button):
    def __init__(self, bot):
        self.bot = bot
        super().__init__(
            label="Accept the Rules here!",
            style=discord.enums.ButtonStyle.green,
            custom_id="interaction:RoleButton",
        )

后续实例化时传入self.bot即可,不会再触发参数数量不匹配的报错。注意持久化视图注册不要放在Cog的__init__里,必须等on_ready事件触发后再注册,否则可能因为bot未完全初始化报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:57:12