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

Discord按钮中.wait()与.stop()函数配合失效问题求助

问题解决:Discord按钮点击后无法终止view.wait()循环

核心错误原因

你代码里的interaction:discord.Interaction.stop()是完全错误的语法——这不是调用停止方法,而是试图给变量加类型注解,根本没有执行终止view.wait()的操作。要让await view.wait()结束,必须调用View对象的stop方法,也就是view.stop()。

其他问题及完整修正方案

除了核心错误,你的代码还有几个会导致异常或逻辑问题的点,以下是修正后的代码和对应说明:

修正后的代码

import csv
import datetime
import discord
from discord import ButtonStyle, Button, View
from discord.ext import commands

@bot.tree.command(name='reminder')
async def reminder(interaction: discord.Interaction):
    # 先延迟响应,避免交互超时
    await interaction.response.defer(ephemeral=False)
    
    with open("C:/Users/market.csv", "r", newline='') as incsv, open("C:/Users/market2.csv", "w+", newline='') as outcsv:
        reader = csv.reader(incsv)
        writer = csv.writer(outcsv)
        
        for row in reader:
            if row[1] == "no":
                # 每次循环创建新的View和按钮,避免重复添加导致多按钮问题
                view = View()
                
                # 绑定当前行的副本,解决闭包引用问题
                async def buttonyes_callback(interaction: discord.Interaction, row=row.copy()):
                    row[1] = 'yes'
                    writer.writerow(row)
                    await interaction.response.edit_message(content="Offer is canceled", embed=None, view=None)
                    view.stop()  # 终止view.wait()
                
                async def buttonno_callback(interaction: discord.Interaction, row=row.copy()):
                    writer.writerow(row)
                    await interaction.response.edit_message(content="Offer is still running", embed=None, view=None)
                    view.stop()
                
                buttonyes = Button(label="YES", style=ButtonStyle.green, custom_id="1")
                buttonno = Button(label="NO", style=ButtonStyle.red, custom_id="2")
                
                buttonyes.callback = buttonyes_callback
                buttonno.callback = buttonno_callback
                
                view.add_item(buttonyes)
                view.add_item(buttonno)
                
                embed = discord.Embed(
                    title='REMINDER',
                    description=f'Is your {row[2]} over ?',
                    color=65280,
                    timestamp=datetime.datetime.now()
                )
                embed.add_field(name='Model', value=row[3], inline=True)
                embed.add_field(name='Size', value=row[4], inline=True)
                embed.add_field(name='Price', value=f"{row[5]}€", inline=True)
                
                # 用followup发送消息,因为初始响应已延迟
                msg = await interaction.followup.send(embed=embed, view=view, wait=True)
                await view.wait()
            else:
                writer.writerow(row)

关键修改说明

  1. 修复stop调用:将错误语法改为view.stop(),这是触发await view.wait()结束的唯一正确方式。
  2. 每次循环创建新View:避免同一个View被重复添加按钮,导致消息中出现多个相同按钮,同时保证每个提醒的交互独立。
  3. 延迟初始响应:先调用await interaction.response.defer(),防止循环处理耗时导致交互超时,后续用followup.send发送每个提醒。
  4. 解决闭包引用问题:在回调函数中添加row=row.copy()参数,确保每个回调引用的是当前循环行的副本,不会因为闭包特性引用到最后一行数据。
  5. 修正重复写入:移除发送消息前的冗余writer.writerow(row),只在需要时写入数据,避免生成重复行。

额外注意事项

  • 如果需要长时间等待用户点击,创建View时可以设置timeout=None(view = View(timeout=None)),避免超时自动终止。
  • 确保机器人拥有发送、编辑消息的权限。
  • 处理完成后,market2.csv会是处理后的结果,可根据需求替换原CSV文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:40:42