if savescores == "y":
name = raw_input("Enter your name.")
datfile = filename[0:-4] + ".dat"
highscores = shelve.open(datfile)
try:
highscores[name].append(score)
except:
highscores[name] = [score]
Run Code Online (Sandbox Code Playgroud)
如果这个特定的玩家已经有分数,我想将新分数附加到他已经拥有的分数上,但显然这不起作用,因为它根本不会改变他的分数.
该Shelf对象未检测到工具架中可变对象的更改.它只检测分配.
要解决此问题,请打开您的架子writeback=True并确保close完成后.(您也可以sync经常降低缓存的内存使用率.)
相关文档来自shelve.open:
由于Python语义,架子无法知道何时修改了可变的持久字典条目.默认情况下,只有在分配给工具架时才会编写修改的对象(请参见示例).如果可选
writeback参数设置为True,访问的所有项目也缓存在内存中,并在写回sync()和close(); 这可以使持久化字典中的可变条目变得更容易,但是,如果访问了许多条目,它可能会占用大量的内存用于缓存,并且它可以使关闭操作非常慢,因为所有访问的条目都被写回(没有办法确定哪些访问的条目是可变的,哪些是实际变异的.
请注意,您可以跳过与开放writeback=True,以节省内存,但你的代码会更加冗长如本例从shelve文档.
# as d was opened WITHOUT writeback=True, beware:
d['xx'] = [0, 1, 2] # this works as expected, but...
d['xx'].append(3) # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
# having opened d without writeback=True, you need to code carefully:
temp = d['xx'] # extracts the copy
temp.append(5) # mutates the copy
d['xx'] = temp # stores the copy right back, to persist it
# or, d=shelve.open(filename,writeback=True) would let you just code
# d['xx'].append(5) and have it work as expected, BUT it would also
# consume more memory and make the d.close() operation slower.
d.close() # close it
Run Code Online (Sandbox Code Playgroud)
顺便说一下,这段代码
try:
highscores[name].append(score)
except:
highscores[name] = [score]
Run Code Online (Sandbox Code Playgroud)
更简洁地表达为
highscores.setdefault(name, []).append(score)
Run Code Online (Sandbox Code Playgroud)