使用discord.py开发提醒命令出现_asyncio.Future不可下标错误
问题原因与修复方案
核心报错原因
你使用的是异步MongoDB驱动(如Motor),collection.find({}).to_list()为异步方法,未添加await关键字时返回的是_asyncio.Future对象而非实际查询结果列表,遍历该对象时自然无法通过下标读取属性,触发对应报错。
其余隐藏问题
- 额外的集合包装与冗余时间解析:你将
reminder['time']用{}包裹会生成集合对象,且你存入数据库的time字段本身就是datetime类型,无需转字符串再用strptime二次解析。 - 实例属性引用错误:类初始化存储的是
self.bot,你后续调用self.client.get_guild不存在,会触发属性错误。 - 时间解析逻辑错误:
int(time[0])仅支持个位数时长输入,输入如10h时只会取第一位的1计算,结果完全不符合预期。 - 未删除到期提醒:触发后的提醒未从数据库删除,会导致每次定时任务执行都重复给用户发消息。
修正后代码
from datetime import datetime, timedelta import discord from discord.ext import commands, tasks # 确保你用的是异步Motor驱动的collection实例 class remind(commands.Cog): def __init__(self, bot): self.bot = bot self.reminder_task.start() def cog_unload(self): self.reminder_task.cancel() @tasks.loop(minutes=1.0) async def reminder_task(self): # 加await获取实际查询结果 data = await collection.find({}).to_list(length=None) now = datetime.now() for reminder in data: # 直接取datetime类型的time字段,无需转义解析 remind_time = reminder['time'] if now >= remind_time: # 用self.bot替代不存在的self.client guild = self.bot.get_guild(reminder['GuildID']) if guild: member = guild.get_member(reminder['author_id']) if member: try: await member.send(f"Reminder: `{reminder['msg']}`") except: # 处理用户关闭DM的情况 pass # 提醒触发后从数据库删除对应记录,避免重复发送 await collection.delete_one({"_id": reminder['_id']}) @slash_commands.command(name="remind", description="create a reminder!", options=[Option("time", "time until I remind you", Type.STRING, required=True), Option("reminder", "what should I remind you about?", Type.STRING, required=True)], guild_ids=bonbot_support) async def remind(self, ctx, time, reminder): if ctx.author.bot: return time_conversion = {"s": 1, "m": 60, "h": 3600, "d": 86400, "w": 604800} # 修正时间解析逻辑,取除最后一位外的所有字符转int try: remindseconds = int(time[:-1]) * time_conversion[time[-1].lower()] except: await ctx.send("时间格式错误,示例:10m、2h、3d", ephemeral=True) return remindertime = datetime.now() + timedelta(seconds=remindseconds) author_id = ctx.author.id guild_id = ctx.guild.id rem_info = {"author_id": author_id, "GuildID": guild_id, "time": remindertime, "msg": reminder} await collection.insert_one(rem_info) await ctx.send(f'Reminder was set! 我会在{remindertime.strftime("%Y-%m-%d %H:%M")}提醒你', ephemeral=True) def setup(bot): bot.add_cog(remind(bot))
内容的提问来源于stack exchange,提问作者judger
相关产品推荐
相关产品推荐

