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

Discord.py选择菜单冷却功能报错:AttributeError问题求助

解决Discord.py选择菜单冷却功能的AttributeError问题

问题原因

报错AttributeError: 'panelSelect' object has no attribute 'cooldown'的核心原因是:你将冷却对象cooldown定义在了视图类panelSelectView中,但在选择菜单类panelSelect的callback方法里,试图通过self.cooldown调用这个属性——而self在这里指向的是panelSelect实例,并非父视图panelSelectView,自然找不到该属性。

解决方案(推荐方法)

直接通过interaction.view获取父视图的冷却对象,无需修改类的初始化逻辑,代码改动最小:

修改后的完整代码

import discord, json
from discord.ext import commands
from discord import app_commands
from variables import ticketData, ticketSetup, closeTicket

class panelSelect(discord.ui.Select):
    def __init__(self):
        options=[
            discord.SelectOption(label="Questions",emoji="❓",description="Any questions you would like to ask the staff team."),
            discord.SelectOption(label="Applying for Roles",emoji="✨",description="Apply for some roles like YouTuber or Godbridger."),
            discord.SelectOption(label="Report",emoji="👮",description="Report a member in the server for breaking rules."), 
            discord.SelectOption(label="Others",emoji="⚠️",description="Any other reasons for opening a ticket.")
        ]
        super().__init__(placeholder="Select a ticket category...",max_values=1,min_values=1,options=options, custom_id="selectTicketTypeView")
    
    async def callback(self, interaction: discord.Interaction):
        # 直接从视图获取冷却对象,无需修改message的author
        bucket = interaction.view.cooldown.get_bucket(interaction)
        retry = bucket.update_rate_limit()
        if retry:
            return await interaction.response.send_message(f"Slow down! Try again in {round(retry, 1)} seconds.", ephemeral=True)
        
        if self.values[0] == "Questions":
            await ticketSetup(
                interaction=interaction,
                fields=["1. What is your question?|Explain your question, in detail, while waiting for a staff member arrives."])
        elif self.values[0] == "Applying for Roles":
            await ticketSetup(
                interaction=interaction,
                fields=["1. What role would you like to apply for?|What role are you aiming to get?","2. Proof|If this applies to your role, what is the proof that you would be eligible for the role?"])
        elif self.values[0] == "Report":
            await ticketSetup(
                interaction=interaction,
                fields=["Who are you reporting?|Please mention the member you are reporting.","What rule did they break?|Which rule did the member break in <#735346274886483988>?","Provide some proof.|Give us a screenshot, jump url or any sufficient proof that proves that they broke a rule. "])
        elif self.values[0] == "Others": 
            await ticketSetup(
                interaction=interaction,
                fields=["Why did you open this ticket?|You selected the `Others` category so please explain your query."])
          
class panelSelectView(discord.ui.View):
    def __init__(self, *, timeout = None):
        super().__init__(timeout=timeout)
        self.cooldown = commands.CooldownMapping.from_cooldown(1, 60, commands.BucketType.member)
        self.add_item(panelSelect())  # 保持原有添加逻辑

关键改动说明

  1. 移除了不必要的interaction.message.author = interaction.user,因为CooldownMapping.get_bucket()可以直接接收interaction对象作为参数,无需修改message属性。
  2. 将self.cooldown替换为interaction.view.cooldown,通过interaction.view直接访问当前视图实例的冷却属性。

备选方案(通过初始化传参)

如果你偏好将冷却对象绑定到选择菜单实例本身,可以修改类的初始化逻辑:

class panelSelect(discord.ui.Select):
    def __init__(self, cooldown):
        self.cooldown = cooldown  # 保存冷却对象到选择菜单实例
        options=[
            # 选项内容不变
        ]
        super().__init__(placeholder="Select a ticket category...",max_values=1,min_values=1,options=options, custom_id="selectTicketTypeView")
    
    async def callback(self, interaction: discord.Interaction):
        bucket = self.cooldown.get_bucket(interaction)
        retry = bucket.update_rate_limit()
        if retry:
            return await interaction.response.send_message(f"Slow down! Try again in {round(retry, 1)} seconds.", ephemeral=True)
        # 后续逻辑不变

class panelSelectView(discord.ui.View):
    def __init__(self, *, timeout = None):
        super().__init__(timeout=timeout)
        self.cooldown = commands.CooldownMapping.from_cooldown(1, 60, commands.BucketType.member)
        self.add_item(panelSelect(self.cooldown))  # 初始化时传入冷却对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:56:14