在不同的文件中加载pickled对象-Attribu

2024-04-20 03:06:00 发布

您现在位置:Python中文网/ 问答频道 /正文

在一个模块中加载pickle文件时遇到了一些问题,该模块与我pickle文件的模块不同。我知道有以下线索:Unable to load files using pickle and multipile modules。我已经尝试了将类导入到正在取消对文件的锁定的模块中的建议解决方案,但它始终给我相同的错误: AttributeError: Can't get attribute 'Document' on <module '__main__' from ''>

我要做的基本结构是:

pickle和unpickle对象的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)

定义文档对象并调用save util方法的文件,类:

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文件是一个需要相当长时间的预处理步骤。我怎么能解决这个问题?


Tags: 模块文件pathpyimportdocmaindef
2条回答

在您的class_def.py文件中有以下代码:

if __name__ == '__main__':
    doc = Document()
    utils.save_document(doc)

这意味着doc将是一个__main__.Document对象,因此当它被pickle时,它期望能够从主模块获得一个Document类,要解决这个问题,需要使用名为class_def的模块中的Document定义,这意味着您将在此处添加导入:

(一般来说,您只需在if __name__ == "__main__"内部执行from <own module name> import *

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)

这样,它将需要运行类def.py文件两次,一次作为__main__,一次作为class_def,但这确实意味着数据将被pickle为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)

尽管通常我更喜欢第一种方式。

我有一个类似的问题,只是刚刚意识到我们的实现之间的差异。

您的文件结构:

  • 实用程序
    • 定义pickle函数
  • 类别定义py
    • 导入实用程序
    • 定义类
    • 制造实例
    • 调用save pickle
  • 处理.py
    • 导入实用程序
    • 加载pickle

我的错误(使用您的文件名)是第一个:

  • util_and_类.py
    • 定义类
    • 定义pickle函数
    • 制造实例
    • 调用save pickle
  • 处理.py
    • 导入util_和_类
    • 调用加载pickle<;<;错误

是什么解决了我的pickle导入问题:

  • util_and_类.py
    • 定义类
    • 定义pickle函数
  • pickle_init.py泡菜
    • 导入util_和_类
    • 制造实例
    • 调用save pickle
  • 处理.py
    • 调用加载pickle

这有一个受欢迎的副作用,即我不需要导入util_和_类文件,因为它已经烘焙到pickle文件中。调用实例并将pickle保存在单独的文件中,解决了在不同于我pickle文件的模块中加载pickle文件的问题

相关问题 更多 >