我一直在阅读本书中的练习,但我遇到了一些障碍。挑战在于:
“改进Trivia Challenge游戏,使其在文件中保留一个高分列表。该程序应记录玩家的名字和分数。使用腌制对象存储高分。”
我已成功将分数保存到列表中,然后将此列表附加到dat文件中。但是,当我尝试查看分数/读取文件时,它似乎只显示输入的第一个分数。我看了一下bat文件,它似乎正确地倾倒了列表,所以我想知道我是否弄乱了检索部分?
感谢您阅读
这是代码(BEFORE):
def high_score():
"""Records a player's score"""
high_scores = []
#add a score
name = input("What is your name? ")
player_score = int(input("What is your score? "))
entry = (name, player_score)
high_scores.append(entry)
high_scores.sort(reverse=True)
high_scores = high_scores[:5] # keep only top five
# Open a new file to store the pickled list
f = open("pickles1.dat", "ab")
pickle.dump(high_scores, f)
f.close()
choice = None
while choice !="0":
print(
"""
0 - Quit
1 - Show high scores
"""
)
choice = input("choice: ")
print()
# exit
if choice == "0":
print("Goodbye")
# show a score
if choice == "1":
f = open("pickles1.dat", "rb")
show_scores = pickle.load(f)
print(show_scores)
f.close()
input("\n\nPress enter to exit.")
解决方案(之后):
def high_score():
"""Records a player's score"""
# no previous high score file
try:
with open("pickles1.dat", "rb") as f:
high_scores = pickle.load(f)
except EOFError:
high_scores = []
#add a score // Do current stuff for adding a new score...
name = input("What is your name? ")
player_score = int(input("What is your score? "))
entry = (name, player_score)
high_scores.append(entry)
high_scores.sort(reverse=True)
high_scores = high_scores[:5] # keep only top five
# dump scores
with open("pickles1.dat", "wb") as f:
pickle.dump(high_scores, f)
答案 0 :(得分:2)
f = open("pickles1.dat", "ab")
# ^
您已在“追加”模式下打开文件。那很好,但它可能没有做你想要的。每次尝试将数据保存到这样的文件时,它都会被添加到最后。您必须阅读您编写的每一个项目以获得最近编写的内容。相反,在写入模式下打开文件。这样,每次都会替换其内容:
f = open("pickles1.dat", "wb")
或者,您可以使用追加,但您必须反复调用pickle.load()
以查看所有已写入的值。这是伪代码,首先是前者,"w"
scores = pickle.load(open('scores.dat', 'rb'))
scores.append(123)
pickle.dump(scores, open('scores.dat', 'wb'))
和后者:
pickle.dump(123, open('scores.dat', 'ab'))
scores = []
with open('scores.dat', 'rb') as f:
while True:
try:
scores.append(pickle.load(f))
except EOFError:
break
我希望你能明白为什么我认为前者(覆盖)更好;它简单得多。
答案 1 :(得分:1)
您的代码存在一些问题。 @TokenMacGuy已经确定了一个,即您将结果附加到输出文件的末尾,而不是覆盖以前的值。
但是有一个更基本的问题。当您运行highscores
功能时,您总是从空的高分列表开始。然后,您可以为其添加一个分数,然后将其写出来。使用这种结构,您一次不会写入多个分数(因此,即使您要回读正确编写的内容,它也只会获得1个元素的列表。)
在添加新值之前,您需要添加一些代码以在函数开头加载文件中的高分列表。当没有以前的高分文件时,您需要设置一个特殊情况,但对于try
/ except
块并不是太困难。这是一些缩写代码:
def high_score():
try:
with open("pickles1.dat", "rb") as f:
high_scores = pickle.load(f)
except FileNotFoundError:
high_scores = []
# do current stuff for adding a new score, sorting and slicing
with open("pickles1.dat", "wb") as f: # "wb" mode overwrites the previous file
pickle.dump(high_scores, f)
# do other stuff, like displaying high_scores
此方法的一个好处是,如果用户要求,您无需稍后重新读取该文件,因为high_scores
列表已经是最新的。