Discord.py如何用单个函数实现多按钮嵌入?优化重复代码
优化Discord.py角色分配按钮的DRY方案
要解决重复按钮装饰器的问题,核心思路是将按钮配置与逻辑分离:把所有按钮的差异化参数(标签、样式、Emoji、角色名)整理成配置列表,再通过循环动态生成按钮并绑定通用的回调逻辑,彻底消除代码重复。
优化后的代码示例
import discord from functools import partial class RoleView(discord.ui.View): def __init__(self): super().__init__(timeout=None) # 统一维护所有按钮的配置项,新增/修改按钮只需调整这里 button_configs = [ {"label": "Sistemas", "style": discord.ButtonStyle.red, "emoji": "💻", "rol": "Sistemas"}, {"label": "Quimica", "style": discord.ButtonStyle.green, "emoji": "🧪", "rol": "Quimica"}, {"label": "Electrica", "style": discord.ButtonStyle.blurple, "emoji": "⚡", "rol": "Electrica"}, {"label": "Mecanica", "style": discord.ButtonStyle.gray, "emoji": "⚙️", "rol": "Mecanica"}, ] # 循环生成按钮并绑定回调 for config in button_configs: button = discord.ui.Button( label=config["label"], style=config["style"], emoji=config["emoji"] ) # 使用partial绑定当前按钮对应的角色名,避免闭包变量捕获问题 button.callback = partial(self._handle_button_click, rol=config["rol"]) self.add_item(button) # 通用的按钮点击回调逻辑 async def _handle_button_click(self, interaction: discord.Interaction, rol: str): await self.give_role(interaction, rol) # 原有的角色分配逻辑保持不变 async def give_role(self, interaction: discord.Interaction, role_name: str): role = discord.utils.get(interaction.guild.roles, name=role_name) if role: await interaction.user.add_roles(role) await interaction.response.send_message(f"已添加角色 {role_name}", ephemeral=True) else: await interaction.response.send_message(f"未找到角色 {role_name}", ephemeral=True)
方案优势
- 符合DRY原则:仅需维护
button_configs列表,新增按钮仅需添加一条配置,无需重复编写回调函数和装饰器。 - 逻辑统一:所有按钮共用同一个回调逻辑,后续修改角色分配规则只需改动
_handle_button_click或give_role方法,无需逐个修改按钮。 - 可扩展性强:如果需要新增更多按钮,直接在配置列表中添加条目即可,代码结构清晰。
内容的提问来源于stack exchange,提问作者ethereumUser
相关产品推荐
相关产品推荐

