Загрузка маринованного объекта в другой файл - ошибка атрибута
У меня возникли проблемы с загрузкой протравленного файла в модуль, отличный от модуля, в котором я запечатлел файл. Мне известна следующая тема: Невозможно загрузить файлы с помощью модулей pickle и multipile. Я попробовал предлагаемое решение импорта класса в модуль, где я распаковываю свой файл, но он продолжает выдавать мне ту же ошибку:AttributeError: Can't get attribute 'Document' on <module '__main__' from ''>
Основная структура того, что я пытаюсь сделать:
Util-файл, который выбирает и удаляет объекты, utils.py:
import pickle
def save_document(doc):
from class_def import Document
write_file = open(file_path, 'wb')
pickle.dump(doc, write_file)
def load_document(file_path):
from class_def import Document
doc_file = open(file_path, 'rb')
return pickle.load(doc_file)
Файл, в котором определен объект Document и вызван метод save util, class_def.py:
import utils
class Document(object):
data = ""
if __name__ == '__main__':
doc = Document()
utils.save_document(doc)
Файл, в котором вызывается метод load util, process.py:
import utils
if __name__ == '__main__':
utils.load_document(file_path)
Запуск process.py дает упомянутый AttributeError. Если я импортирую файл class_def.py в process.py и запусту его основной метод, как упомянуто в исходном потоке, он будет работать, но я хочу иметь возможность запускать эти два модуля по отдельности, поскольку файл class_def - это этап предварительной обработки, который занимает довольно много времени. когда-то. Как я мог решить это?
2 ответа
В вашем class_def.py
файл у вас есть этот код:
if __name__ == '__main__':
doc = Document()
utils.save_document(doc)
Это означает, что doc
будет __main__.Document
объект, поэтому, когда он маринован, он ожидает, что сможет получить Document
класс из основного модуля, чтобы исправить это, вам нужно использовать определение Document
из модуля под названием class_def
то есть вы бы добавили сюда импорт:
if __name__ == '__main__':
from class_def import Document
# ^ so that it is using the Document class defined under the class_def module
doc = Document()
utils.save_document(doc)
таким образом, нужно будет запустить файл class_def.py дважды, один раз как __main__
и как только class_def
но это означает, что данные будут засолены как class_def.Document
объект, загружающий его, извлечет класс из правильного места. В противном случае, если у вас есть способ создать один объект документа из другого, вы можете сделать что-то подобное в utils.py
:
def save_document(doc):
if doc.__class__.__module__ == "__main__":
from class_def import Document #get the class from the reference-able module
doc = Document(doc) #convert it to the class we are able to use
write_file = open(file_path, 'wb')
pickle.dump(doc, write_file)
Хотя обычно я предпочитаю первый способ.
У меня была похожая проблема, и я только что понял различия между нашими реализациями.
Ваша файловая структура:
- util.py
- определить функции рассола
- class_def.py
- утилита импорта
- определить класс
- сделать экземпляр
- позвоните сохранить рассол
- process.py
- утилита импорта
- маринованный груз
Моя ошибка (используя ваши имена файлов) была первой:
- util_and_class.py
- определить класс
- определить функции рассола
- сделать экземпляр
- позвоните сохранить рассол
- process.py
- import util_and_class
- вызов загрузки маринада << ОШИБКА
Что решило мою проблему импорта маринадов:
- util_and_class.py
- определить класс
- определить функции рассола
- pickle_init.py
- import util_and_class
- сделать экземпляр
- позвоните сохранить рассол
- process.py
- вызов загрузки
Это имело приятный побочный эффект: мне не нужно было импортировать файл util_and_class, поскольку он запекается в файл pickle. Вызов экземпляра и сохранение рассола в отдельном файле __name__
проблема "загрузки протравленного файла в модуль, отличный от модуля, в котором я запечатлел файл".