反序列化错误:无效加载键'(heart)
我最近在玩一个叫pickle的东西,想把它用在一个“猜数字”练习程序的高分系统里。我以为我已经理解这个概念了,但现在出现了一个错误,我完全不知道为什么。
这是相关的代码:
def EnterHighScore(score,scoresList):
name = input("Enter your name: ")
newPlayer = player(name,score)
scoresList.append(newPlayer)
scoresFile = open('scores','wb')
pickle.dump(scoresList,scoresFile)
scoresFile.close()
for i in scoresList:
print(i.name + ' - ' + str(i.score))
def CheckHighScores(score):
try:
scoresFile = open('scores','rb')
except:
scoresFile = open('scores','wb+')
if not scoresFile.read(1):
scoresList = []
else:
scoresList = pickle.load(scoresFile)
scoresFile.close()
if not scoresList:
EnterHighScore(score,scoresList)
else:
for counter,i in enumerate(scoresList):
if counter == 3:
break
if score >= i.score:
EnterHighScore(score,scoresList)
break
当我运行这个程序时,第一次运行是没问题的。也就是说,当'scores'文件根本不存在的时候,它会正确创建这个文件,scoresList会先是空的,然后填入一个玩家对象,最后把它保存到scoresFile里,没有任何错误。但是当我尝试用新的'scores'文件数据来加载scoresList时,就出现了以下错误:
UnpicklingError: Invalid load key'(heart)'
(心)代表一个实际的心形字符。
我看到其他人也遇到过这个问题,但他们的情况是因为在不同的操作系统上打开文件,或者在序列化后但反序列化前修改了文件。而在我的情况下,这个文件根本没有被修改,只是写入并关闭了。
我还尝试在其他更简单的场景中使用pickle,结果没有出现其他错误。
任何帮助都会很感激。
1 个回答
2
你用来检查文件是否为空的测试,会把文件读取指针移动到文件的开头之后:
if not scoresFile.read(1):
你需要把指针再移回到开头:
if not scoresFile.read(1):
scoresList = []
else:
scoresFile.seek(0)
scoresList = pickle.load(scoresFile)
一个更好的方法是捕获 pickle.load()
抛出的 EOFError
异常,这个异常会在文件为空时出现:
try:
scoresList = pickle.load(scoresFile)
except EOFError:
# File empty
scoresList = []
或者你可以捕获 IOError
,当文件不存在时就会出现这个错误:
try:
with open('scores','rb') as scoresFile:
scoresList = pickle.load(scoresFile)
except IOError:
scoresList = []
这样你就可以在这里不打开文件进行写入了。