pickle.load() 在末尾添加一个 None 对象

pickle.load() adds a None object at the end

你好,我正在学习 Python 并尝试创建一个命令行地址簿作为 dictionary,它使用 [=20] 保存到一个文件=](这是简报)。

我编写了 add_contactbrowse_contact 函数,它们都运行良好。我在地址簿中添加了一些联系人(他们的名字只是“测试一”、“测试二”...“测试十”)以及他们的电子邮件和 phone 号码。

但是,当我编写 search_contactmodify_contact 函数时,我需要使用 pickle.load().[=45 将文件加载回 dictionary =]

问题是,由于每个联系人都是一个一个添加到地址簿中的,如果我简单地使用以下代码,它只会return地址簿中的第一个对象:

with open("addressbook.data", "rb") as f:
    loaded_contacts = pickle.load(f)
    print(loaded_contacts)

输出:

{'Test One': ('test.one@jdsofj.com', '39893849')}

那是因为“Pickle 一次序列化一个对象,然后读回一个对象。”根据建议的解决方案 ,我更改为以下代码,因此我可以将所有对象加载回名为 loaded_contacts:

的字典中
with open("addressbook.data", "rb") as f:
    while True:
        try:
            loaded_contacts = print(pickle.load(f))
        except EOFError:
            break

这似乎可行,但是从文件加载的字典将在末尾有一个额外的 None 对象,一旦 loaded_contacts 被打印出来,如下所示:

{'Test One': ('test.one@jdsofj.com', '39893849')}
{'Test Two': ('test.two@clajdf.com', '93294798374')}
.
.
.
{'Test Ten': ('test.ten@oajfd.com', '79854399')}
None

因此,当我尝试搜索“Test One”之类的名称并尝试检索其值时,我将得到 TypeError: 'NoneType' object is not subscriptable,因为末尾有一个 None 对象。

这是代码(它需要更多的工作,但你会明白的):

with open("addressbook.data", "rb") as f:
    while True:
        try:
            loaded_contacts = print(pickle.load(f))
        except EOFError:
            break

search_name = input("Please enter a name: ")
print(loaded_contacts[search_name])

这是我输入名称后的错误消息:

TypeError                                 Traceback (most recent call last)
/var/.../x.py in <module>
     11 
     12 search_name = input("Please enter a name: ")
---> 13 print(loaded_contacts[search_name])
     14 

TypeError: 'NoneType' object is not subscriptable

不确定我做错了什么,或者为什么在加载的字典末尾有一个额外的 None 对象(或如何删除它)。我知道我可以使用列表将所有值存储为字符串,但简报是创建一个 dictionary 来保存所有值并使用 dictionary built-in methods 添加、删除和修改联系人--因此我的问题在这里。

编辑更新:

问题的答案(感谢@JohnGordon 和@ewong):

loaded_contacts = print(pickle.load(f)) 中,print() 不会 return 任何东西,因此将变量分配给 print() 将 return Noun

然而,简单地删除 print() 不会完全起作用——它解决了 'None' 问题,但是 loaded_contacts 只会被分配给 [的最后一次迭代的值=41=].

以下是如何迭代 pickle.load(f) 中的所有对象(如果它们最初是一个一个添加的),然后将它们全部存储在 dictionary:

loaded_contacts = {} # create an empty dictionary

with open("addressbook.data", "rb") as f: # open the file
    while True: # looping pickle.load(f)
        try:
            # add each object to the dictionary
            loaded_contacts.update(pickle.load(f))
        except EOFError:
            break # stop looping at the end of the file
loaded_contacts = print(pickle.load(f))

这是你的问题。您正在将 loaded_contacts 分配给 print() 的 return 值,它不会 return 任何东西,因此默认情况下它 returns None .

改为这样做:

loaded_contacts = pickle.load(f)
print(loaded_contacts)