在Python中为键添加值?

2 python append shelve pickle

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)

如果这个特定的玩家已经有分数,我想将新分数附加到他已经拥有的分数上,但显然这不起作用,因为它根本不会改变他的分数.

Ste*_*ski 6

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)