如何在Discord.py的while循环中编辑Embed?及代码执行异常排查
Discord Embed 复用与代码逻辑问题解决
一、代码阻塞(后续未执行)的原因
你的代码在发送Embed消息后,立刻执行await client.wait_for("message"),这个方法会阻塞当前协程,直到有新消息被触发:
- 如果10秒内没有任何消息发送,就会触发
asyncio.TimeoutError,打印"Stopped"后回到循环开头,再次等待消息; - 如果没有消息触发,更新数据的逻辑永远不会执行,看起来就像后续代码没跑起来。
而且你的需求是循环100次自动更新,这个wait_for逻辑完全不符合需求——它把更新触发条件变成了“收到消息”,而非自动循环。
二、复用单个Embed实例的方法
不需要每次新建discord.Embed对象,直接复用最初创建的实例,通过内置方法修改内容即可:
- 使用
set_title()修改标题 - 使用
set_description()修改描述 - 也可以直接修改实例的属性(如
embed.title = "新标题")
修改完成后,调用await user_msg.edit(embed=你的实例)就能更新消息。
三、修改后的完整代码
以下代码实现自动循环100次更新Embed,同时复用单个Embed实例,去掉了多余的wait_for逻辑,加入了更新间隔(可自行调整):
import asyncio import requests import json import discord # 假设parse_json是你定义的解析函数 def parse_json(data): # 这里是你的解析逻辑,示例返回结构 return { 'data1': data.get('price'), 'data2': data.get('volume'), 'data3': data.get('range'), 'data4': data.get('high'), 'data5': data.get('low') } # 命令逻辑部分 async def your_command_function(ctx, symbol): url = f'https://someapirequest' count = 0 # 初始化单个Embed实例 real_embed = discord.Embed(colour=0xFF8300) user_msg = await ctx.send(embed=real_embed) while count < 100 and not client.is_closed(): try: count += 1 # 请求数据 response = requests.get(url, headers={'User-agent': 'Mozilla/5.0'}) data = json.loads(response.text) pj = parse_json(data) price = pj['data1'] volume = pj['data2'] marketRange = pj['data3'] high = pj['data4'] low = pj['data5'] # 复用real_embed实例,修改内容 real_embed.set_title(f"{symbol} Realtime Data:") real_embed.description = f'Price: ${price} Volume: {volume} Range: {marketRange} High: ${high} Low: ${low} Count: {str(count)}' # 更新消息 await user_msg.edit(embed=real_embed) # 设置更新间隔(比如每5秒更新一次,可自行调整) await asyncio.sleep(5) except Exception as e: print(f"Error: {e}") # 出错后短暂等待再重试,避免频繁请求 await asyncio.sleep(2) print("更新完成")
补充说明
- 如果你的需求确实是收到消息才更新一次,那需要确保有消息发送到对应频道,
wait_for才会触发后续逻辑;但这种情况下循环100次需要用户发100条消息,显然不符合“持续更新”的需求。 - 建议使用异步请求库(如
aiohttp)替代requests,避免阻塞协程,提升机器人响应性能。
内容的提问来源于stack exchange,提问作者Cr3
相关产品推荐
相关产品推荐

