从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
相关产品推荐
相关产品推荐

