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]
If this specific player already has a score, I want to append the new score to the scores he already has, but apparently this doesn't work, because it doesn't change his score at all.
The Shelf
object does not detect changes to mutable objects in your shelf. It only detects assignment.
To fix this, open your shelf with writeback=True
and make sure to close
when you are done. (You can also sync
every so often to lower memory usage of the cache.)
Relevant docs from shelve.open
:
Because of Python semantics, a shelf cannot know when a mutable persistent-dictionary entry is modified. By default modified objects are written only when assigned to the shelf (see Example). If the optional
writeback
parameter is set toTrue
, all entries accessed are also cached in memory, and written back onsync()
andclose()
; this can make it handier to mutate mutable entries in the persistent dictionary, but, if many entries are accessed, it can consume vast amounts of memory for the cache, and it can make the close operation very slow since all accessed entries are written back (there is no way to determine which accessed entries are mutable, nor which ones were actually mutated).
Note that you can skip opening with writeback=True
to save memory, but your code will be more verbose as shown in this example from the shelve
docs.
# 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
By the way, this code
try:
highscores[name].append(score)
except:
highscores[name] = [score]
is more concisely expressed as
highscores.setdefault(name, []).append(score)