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()) # 保持原有添加逻辑
关键改动说明
- 移除了不必要的
interaction.message.author = interaction.user,因为CooldownMapping.get_bucket()可以直接接收interaction对象作为参数,无需修改message属性。 - 将
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
相关产品推荐
相关产品推荐

