Discord机器人执行写入用户到JSON的命令时出现KeyError: 'level'错误
问题修复方案
报错原因
你遇到的KeyError: 'level'是因为用户数据的字段名拼写不匹配,叠加命令注册失败、文件操作模式错误几个问题共同导致的。
具体修复步骤
- 修正用户初始化字段名
你的update_data函数里给新用户设置的等级字段是levels(带s后缀),但后续level_up、mylevel里读写的都是level(无s后缀),把update_data里的users[f'{user.id}']['levels']=0改成users[f'{user.id}']['level']=0即可。 - 修复命令注册错误
start_levels的装饰器少了括号,要改成@client.command(),不然你执行-start_levels不会触发对应逻辑。 - 修正文件写入模式
on_message里最后保存用户数据时,你用了只读模式'r'打开文件,写入会直接报错,把with open ('users.json', 'r') as f:改成with open ('users.json', 'w') as f:。 - 补充Intents声明
你初始化Bot时用到的intents变量没有提前定义,Discord API要求必须显式声明消息内容权限才能收到用户消息,在创建client前加两行代码:intents = discord.Intents.default() intents.message_content = True - 修复
mylevel命令错误ctx.author是属性不是方法,把member=ctx.author()改成member=ctx.authorawait ctx.send行缩进错误,要缩进到mylevel函数内部,和lvl=users[str(id)]['level']保持同级。
修正后核心代码示例
import discord from discord.ext import commands import json # 补充intents定义 intents = discord.Intents.default() intents.message_content = True client = commands.Bot(intents = intents, command_prefix="-", case_insensitive=True) @client.event async def on_ready(): print('Bot is Online {0.user}'.format(client)) print("-"*100) game = discord.Game("use prefix '-'") await client.change_presence(status=discord.Status.dnd,activity=game) async def update_data(users, user): if not f'{user.id}' in users: users[f'{user.id}']={} users[f'{user.id}']['exp']=0 # 修正字段名拼写 users[f'{user.id}']['level']=0 async def add_experience(users, user, exp): users[f'{user.id}']['exp']+=exp async def level_up(users, user, message): exp=users[f'{user.id}']['exp'] lvl_start=users[f'{user.id}']['level'] lvl_end=int(exp ** (1/4)) if lvl_start<lvl_end: await message.channel.send(f'{user.mention} has levelled up! **LEVEL {lvl_end}**') users[f'{user.id}']['level'] = lvl_end # 补全装饰器括号 @client.command() async def start_levels(ctx): with open ('users.json','r') as f: users=json.load(f) await update_data(users, ctx.author) with open ('users.json','w') as f: json.dump(users,f,indent=4) @client.event async def on_message(message): if not message.author.bot: with open ('users.json','r') as f: users=json.load(f) await update_data(users, message.author) await add_experience(users, message.author, 5) await level_up(users, message.author, message) # 修正为写入模式 with open ('users.json', 'w') as f: json.dump(users,f,indent=4) await client.process_commands(message) @client.command() async def mylevel(ctx, member:discord.Member=None): if member==None: # 去掉author后的括号 member=ctx.author id=member.id with open ('users.json', 'r') as f: users=json.load(f) lvl=users[str(id)]['level'] # 修正缩进 await ctx.send(f'{member.mention} is on level **{lvl}**') # 替换为你自己的机器人Token client.run("你的机器人Token")
额外注意
如果你的users.json文件是空的,第一次运行前先往里面写个{},不然读取JSON会报错。
内容的提问来源于stack exchange,提问作者user16114868
相关产品推荐
相关产品推荐

