discord.py警告命令触发TypeError(string indices must be integers)求助
解决discord.py警告查询命令的TypeError问题
问题描述
使用discord.py开发的warnings命令查询成员警告记录时,触发如下错误:
Traceback (most recent call last): File "/home/container/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 190, in wrapped ret = await coro(*args, **kwargs) File "/home/container/main.py", line 398, in warnings embed.add_field(name=f"{warn['reason']}", value=f"<@{warn['moderator_id']}>", inline=False) TypeError: string indices must be integers The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/container/.local/lib/python3.9/site-packages/discord/ext/commands/bot.py", line 1347, in invoke await ctx.command.invoke(ctx) File "/home/container/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 986, in invoke await injected(*ctx.args, **ctx.kwargs) # type: ignore File "/home/container/.local/lib/python3.9/site-packages/discord/ext/commands/core.py", line 199, in wrapped raise CommandInvokeError(exc) from exc discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: string indices must be integers
相关代码:
@client.hybrid_command(name = "warnings", with_app_command=True, description="View the warnings of a member", aliases=["punishments"]) @commands.is_owner() async def warnings(ctx, member: discord.Member = None): if member == None: await ctx.reply("A Member is required") else: check = warndb.warn_logs.find_one({"user_id": member.id}) if check is None: await ctx.reply("This user has no warns") else: embed = discord.Embed(color=embedcolor, title=f"{member.name}'s warnings") print(check) for warn in check: embed.add_field(name=f"{warn['reason']}", value=f"<@{warn['moderator_id']}>", inline=False) await ctx.send(embed=embed)
问题原因
warndb.warn_logs.find_one()返回的是字典对象,直接遍历这个字典时,循环变量warn会依次拿到字典的键名(字符串类型),比如user_id、warns这类键。此时尝试用warn['reason']访问字符串的索引,自然会触发错误——字符串只能用整数下标,不能用字符串当索引。
你的数据库结构应该是把用户的所有警告条目存在字典的某个列表字段里(比如warns字段),需要遍历的是这个列表,而非整个字典。
解决方案
修改循环部分,遍历字典中存储警告条目的列表字段(假设字段名为warns,若实际字段名不同,替换为对应名称即可):
@client.hybrid_command(name = "warnings", with_app_command=True, description="View the warnings of a member", aliases=["punishments"]) @commands.is_owner() async def warnings(ctx, member: discord.Member = None): if member == None: await ctx.reply("A Member is required") else: check = warndb.warn_logs.find_one({"user_id": member.id}) if check is None: await ctx.reply("This user has no warns") else: embed = discord.Embed(color=embedcolor, title=f"{member.name}'s warnings") # 遍历存储警告的列表字段,根据实际数据库结构修改字段名 for warn in check['warns']: embed.add_field(name=f"{warn['reason']}", value=f"<@{warn['moderator_id']}>", inline=False) await ctx.send(embed=embed)
额外说明
如果不确定数据库返回的字典结构,可以通过print(check)输出内容,确认警告列表所在的字段名。比如输出可能为:
{"user_id": 123456789, "warns": [{"reason": "刷屏", "moderator_id": 987654321}, {"reason": "辱骂", "moderator_id": 987654321}]}
此时就能明确需要遍历check['warns']这个列表。
内容的提问来源于stack exchange,提问作者TheRealKurumi
相关产品推荐
相关产品推荐

