为什么我不能在 shelf 文件中存储一个存储对象的字典?

Why can't I store in a shelf file a dictionary that stores objects?

我正在使用字典来存储对象。然后将字典存储在 shelf 文件中。从 shelf 文件中检索用于打印东西的字典时,出现错误。

下面的脚本是创建一个shelf文件用于测试:

# creating shelf file for testing
import shelve
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

buddy = Dog("Buddy", 9)
miles = Dog("Miles", 4)
d = {}
d['buddy'] = buddy
d['miles'] = miles
with shelve.open('dogs') as sf:
    sf['d'] = d

然后,下面的脚本读取上面创建的shelf文件:

# reading shelf file and printing stuff

import shelve
with shelve.open('dogs') as sf:
    d = sf['d']

for k in d.keys():
    print(d[k].name, d[k].age)

在运行上面的脚本之后,得到如下错误信息:

Traceback (most recent call last):
  File "C:\Users\jc\AppData\Local\Programs\Python\Python39\lib\shelve.py", line 111, in __getitem__
    value = self.cache[key]
KeyError: 'd'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\Users\jc\OneDrive\Documents\PythonScripts\test2.py", line 23, in <module>
    d = sf['d']
  File "C:\Users\jc\AppData\Local\Programs\Python\Python39\lib\shelve.py", line 114, in __getitem__
    value = Unpickler(f).load()
AttributeError: Can't get attribute 'Dog' on <module '__main__' from 'c:\Users\jc\OneDrive\Documents\PythonScripts\test2.py'>

问题是读取保存的 shelf 的脚本不知道 Dog class.

的定义

shelve 基于 pickle 模块。 pickle 可以序列化 classes 的实例,但它不会序列化 class 本身。 class定义必须存在于读取搁置数据的模块中。

引用documentation

pickle can save and restore class instances transparently, however the class definition must be importable and live in the same module as when the object was stored.

如果您确保 Dog 的定义在读取货架之前在脚本中可用,保存的数据将正确加载。