UnpicklingError:无效的加载密钥'(心脏)'

时间:2014-05-30 21:25:06

标签: python file-io 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

当我运行它时,第一次运行顺利。也就是说,当得分为'文件甚至不存在。它被正确创建,scoreList被创建为空,然后填充了一个玩家对象,它被转储到scoresFile中而没有任何错误。但是当我尝试使用新的'分数加载得分列表时文件数据,它给我以下错误:

UnpicklingError: Invalid load key'(heart)'

(心)代表一个真正的心灵角色。

我已经读过其他人遇到过这个问题,但在这些情况下,他们试图在不同的操作系统中打开文件,或者在酸洗之后但在开启之前以某种方式修改了文件。在这种情况下,文件根本没有被修改,只是写入并关闭。

我尝试过在其他更简单的场景中使用泡菜,但我还没有造成其他错误。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

您的测试以查看文件是否为空会使文件读取指针超过文件的开头:

if not scoresFile.read(1):

你必须回到起点:

if not scoresFile.read(1):
    scoresList = []
else:
    scoresFile.seek(0)
    scoresList = pickle.load(scoresFile)

如果文件为空,一个更好的测试是捕获EOFError抛出的pickle.load()异常:

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 = []

并且只是不打开文件来写这里。