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

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命令错误
    1. ctx.author是属性不是方法,把member=ctx.author()改成member=ctx.author
    2. await 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 21:15:02