#python #shelve
Вопрос:
Я использую словарь для хранения объектов. Затем словарь сохраняется в файле на полке. При извлечении словаря из файла полки для печати материалов появляется ошибка.
Следующий сценарий предназначен для создания файла полки для тестирования:
# 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
Затем следующий сценарий считывает файл полки, созданный выше:
# 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:UsersjcAppDataLocalProgramsPythonPython39libshelve.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:UsersjcOneDriveDocumentsPythonScriptstest2.py", line 23, in <module>
d = sf['d']
File "C:UsersjcAppDataLocalProgramsPythonPython39libshelve.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'>
Ответ №1:
Проблема в том, что скрипт, который считывает сохраненную полку, не знает определения Dog
класса.
shelve
основан на pickle
модуле. pickle
может сериализовать экземпляры классов, но не сериализует сам класс. Определение класса должно существовать в модуле, который считывает отложенные данные.
Чтобы процитировать документацию:
pickle может прозрачно сохранять и восстанавливать экземпляры классов, однако определение класса должно быть импортируемым и находиться в том же модуле, что и при хранении объекта.
Если вы убедитесь, что определение Dog
доступно в сценарии перед чтением полки, сохраненные данные будут загружены правильно.