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

从Shelve读取数组时触发KeyError错误求助

解决你的KeyError问题与排行榜代码优化

让我来帮你一步步搞定这个问题:

核心问题分析

首先看你抛出的KeyError: b'lb',本质是你的shelve存储文件leaderboard里根本不存在'lb'这个键——不管是字符串形式还是字节形式的,所以当你直接执行utemp = ulbs['lb']时,程序直接报错了。

另外你的代码里还有几个明显的低级错误,比如:

  • 打开的是ulbs,但关闭时写的是lbs.close(),这会导致资源泄漏甚至报错
  • while len(temp) > 0里的temp变量根本没定义,应该是utemp
  • 用来分割字符串的x、p变量也没看到定义,硬编码索引的方式很容易出错

分步解决方案

1. 先解决KeyError:初始化shelve键

在读取shelve内容前,先检查'lb'键是否存在,如果不存在就初始化一个空列表,避免直接读取报错:

def sortlb():
    ulbs = shelve.open('leaderboard')
    # 初始化排行榜键,避免首次运行或数据丢失时报错
    if 'lb' not in ulbs:
        ulbs['lb'] = []
        ulbs.sync()  # 确保数据写入磁盘
    utemp = ulbs['lb']
    ulbs.close()  # 这里修正之前的lbs拼写错误
    # 后续逻辑继续...

2. 修正代码里的逻辑错误

  • 把lbs.close()改成ulbs.close(),否则会报NameError
  • 把while len(temp) > 0改成while len(utemp) > 0,因为temp从未定义
  • 替换硬编码的字符串分割逻辑:你现在用"用户名/用户ID,积分"的字符串格式存储,不如直接用字典嵌套列表的形式,操作更直观也不容易出错。

3. 优化排序逻辑(更简洁高效)

原来的循环找最大值的方式冗余且效率低,直接用Python内置的sorted函数就能实现按积分降序排序,同时把存储格式改成字典,代码可读性会高很多:

def sortlb():
    ulbs = shelve.open('leaderboard')
    # 初始化排行榜
    if 'lb' not in ulbs:
        ulbs['lb'] = []
    leaderboard = ulbs['lb']
    ulbs.close()

    # 按积分从高到低排序,reverse=True表示降序
    sorted_board = sorted(leaderboard, key=lambda user: user['points'], reverse=True)
    
    # 生成最终的排行榜文本
    ret = ['Leaderboard:']
    for rank, user in enumerate(sorted_board, start=1):
        ret.append(f"{rank}. {user['username']} - {user['points']} points")
    return ret

4. 调试小技巧

如果不确定shelve里的内容,可以在打开文件后加一行打印代码:

print("当前shelve中的键:", list(ulbs.keys()))

这样就能直观看到'lb'键是否存在。如果原来的shelve文件已经损坏,直接删除leaderboard相关的文件(不同系统后缀可能是.db/.dat等),让程序重新初始化即可。

内容的提问来源于stack exchange,提问作者Gumland

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:33:08