使用Pickle保存分数
我刚接触Python,写了一个程序用来保存高分,使用了一个叫做pickle的字典对象,然后再调用它。我有几个关于我程序的问题,希望有人能帮我解答。
- 如何在多次启动应用时存储和更新这些数据?(退出Python IDLE再重新打开时,这些分数不会被保存)
- 已解决:为什么程序会写入同一个人的新分数,无论是高了还是低了?
-
import pickle
high_scores = {"Adam Smith": 65536, "John Doe": 10000}
with open("highscores.pkl","wb") as out:
pickle.dump(high_scores, out)
new_score = (raw_input("Enter your name ").title(), int(raw_input("Enter your score ")))
with open("highscores.pkl","rb") as in_:
high_scores = pickle.load(in_)
if new_score[0] not in high_scores:
high_scores[new_score[0]] = new_score[1]
if new_score[0] in high_scores and new_score[1] not in high_scores.values():
high_scores[new_score[0]] = new_score[1]
else:
pass
with open("highscores.pkl","wb") as out:
pickle.dump(high_scores, out)
print("-" * 80)
for name, score in high_scores.items():
print("{{name:>{col_width}}} | {{score:<{col_width}}}".format(col_width=(80-3)//2).format(name=name, score=score))
3 个回答
2
为什么程序会写入同一个人的新分数,无论是高还是低?
你并不是在比较分数的大小,而是只是在检查这个分数是否已经存在。
你需要检查一下 if new score is > old score
,然后再把它存储到数据里。
你需要先 load
这个对象,然后再进行检查,最后再 dump
数据,否则每次运行程序时都会覆盖掉之前的数据。
high_scores = {"Adam Smith": 65536, "John Doe": 10000}
with open("highscores.pkl","wb") as out:
pickle.dump(high_scores, out)
每次你启动应用时,都会覆盖掉之前的数据。
在你应用的开头,需要有一些逻辑来检查是否已经有数据被保存,如果没有,那就是第一次运行,所以要设置 high_scores ={}
,然后添加更新的信息。如果里面已经有数据了,就要把它解压出来,然后把存储的值和新的值进行比较。
If the file "highscores.pkl" does not exist, high_score ={} else open the file for reading
Do your comparison check and finally pickle.dump to file.
2
- 使用 `pickle.dump(obj, file)` 可以把对象保存到文件里,而用 `obj = pickle.load(file)` 可以从文件中加载这个对象。看起来你已经做过这些了。
- 试着把
new_score[1] not in high_scores.values()
替换成new_score[1] > high_scores[new_score[0]]
,因为后者实际上是在检查新分数是否比旧分数高。
2
根据Padraic的建议,下面的代码会先检查一下highscores.pkl
这个文件是否存在。如果存在,就把里面的内容读取出来放到high_scores
里;如果不存在,就给high_scores
赋两个默认的分数。
接下来,当输入一个新分数后,我们会检查一下high_scores
里有没有这个玩家的名字(也就是“键”)。如果有,而且新分数比旧分数高,那么就用新分数替换掉旧分数。如果没有这个名字,那就把玩家和分数加进去。
完成这个检查后,high_scores
会被保存到highscores.pkl
这个文件里。
import pickle
import os
high_scores = {}
if os.path.isfile('highscores.pkl'):
with open("highscores.pkl", "rb") as f:
high_scores = pickle.load(f)
else:
high_scores = {"Adam Smith": 65536, "John Doe": 10000}
new_score = (raw_input("Enter your name ").title(), int(raw_input("Enter your score ")))
if new_score[0] in high_scores:
if new_score[1] > high_scores[new_score[0]]:
high_scores[new_score[0]] = new_score[1]
else:
high_scores[new_score[0]] = new_score[1]
with open("highscores.pkl","wb") as out:
pickle.dump(high_scores, out)
print("-" * 80)
for name, score in high_scores.items():
print("{{name:>{col_width}}} | {{score:<{col_width}}}".format(col_width=(80-3)//2).format(name=name, score=score))