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

如何在discord.py中为每个用户设置独立的选中卡片列表?

实现不同用户独立维护选中卡片列表的方案

核心思路

问题根源在于多个用户复用了同一个列表对象,或是没有在View中为每个用户绑定独立的数据。要解决这个问题,需要做到两点:

  1. 每个用户触发的View实例持有独立的选中卡片列表
  2. 在按钮交互时,确保只操作当前用户对应的列表

具体实现方法

方法1:给View实例绑定用户专属状态数据

在View的__init__方法里,为每个实例初始化独立的选中列表,同时记录当前操作的用户ID(避免他人篡改)。

示例代码(基于discord.py):

import discord
from discord.ui import View, Button

class CardSelectView(View):
    def __init__(self, user_id, available_cards):
        super().__init__(timeout=60)
        self.user_id = user_id  # 记录当前操作的用户ID
        self.selected_cards = []  # 每个实例独立的选中列表
        self.available_cards = available_cards

        # 生成卡片选择按钮
        for card in available_cards:
            button = Button(label=card, style=discord.ButtonStyle.primary)
            button.callback = self.card_select_callback
            self.add_item(button)

    async def card_select_callback(self, interaction: discord.Interaction):
        # 只允许指定用户操作
        if interaction.user.id != self.user_id:
            await interaction.response.send_message("这不是你的选择面板哦!", ephemeral=True)
            return
        
        selected_card = interaction.component.label
        if selected_card not in self.selected_cards:
            self.selected_cards.append(selected_card)
            await interaction.response.send_message(f"已选中卡片:{selected_card}", ephemeral=True)
        else:
            self.selected_cards.remove(selected_card)
            await interaction.response.send_message(f"已取消选中卡片:{selected_card}", ephemeral=True)

# 触发View的示例
async def start_card_selection(ctx, user1, user2, available_cards):
    # 给用户1创建独立的View实例
    view1 = CardSelectView(user1.id, available_cards)
    await user1.send("请选择你的专属卡片:", view=view1)
    
    # 给用户2创建独立的View实例
    view2 = CardSelectView(user2.id, available_cards)
    await user2.send("请选择你的专属卡片:", view=view2)

方法2:用全局字典映射用户ID到选中列表

如果需要跨多个View共享用户的选中数据,可以用全局字典,以用户ID为键存储对应列表,适合多View跳转的场景。

示例代码:

import discord
from discord.ui import View, Button

# 全局字典,存储每个用户的选中卡片
user_selections = {}

class CardSelectView(View):
    def __init__(self, user_id, available_cards):
        super().__init__(timeout=60)
        self.user_id = user_id
        self.available_cards = available_cards
        # 初始化该用户的选中列表(如果不存在)
        if user_id not in user_selections:
            user_selections[user_id] = []

        for card in available_cards:
            button = Button(label=card, style=discord.ButtonStyle.primary)
            button.callback = self.card_select_callback
            self.add_item(button)

    async def card_select_callback(self, interaction: discord.Interaction):
        if interaction.user.id != self.user_id:
            await interaction.response.send_message("无权操作此面板!", ephemeral=True)
            return
        
        selected_card = interaction.component.label
        if selected_card not in user_selections[self.user_id]:
            user_selections[self.user_id].append(selected_card)
            await interaction.response.send_message(f"已选中:{selected_card}", ephemeral=True)
        else:
            user_selections[self.user_id].remove(selected_card)
            await interaction.response.send_message(f"已取消选中:{selected_card}", ephemeral=True)

# 跳转到下一个View的示例
class ConfirmView(View):
    def __init__(self, user_id):
        super().__init__(timeout=30)
        self.user_id = user_id

    @discord.ui.button(label="确认选择", style=discord.ButtonStyle.success)
    async def confirm_callback(self, interaction: discord.Interaction, button: Button):
        if interaction.user.id != self.user_id:
            await interaction.response.send_message("无权操作!", ephemeral=True)
            return
        
        # 获取该用户的选中列表
        user_cards = user_selections.get(self.user_id, [])
        await interaction.response.send_message(f"你的最终选中卡片:{', '.join(user_cards)}", ephemeral=True)
        # 操作完成后清理临时数据
        del user_selections[self.user_id]

关键注意事项

  • 绝对不要在多个View实例之间共享同一个列表对象,每个实例要么自己初始化列表,要么通过用户ID映射独立列表。
  • 按钮回调中必须校验用户身份,防止其他用户篡改他人的选中数据。
  • 使用全局字典时,记得在用户操作完成后清理数据,避免内存占用过高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 12:31:00