关于python:在不同文件中加载pickle对象 – 属性错误

Load pickled object in different file - Attribute error

我在一个模块中加载一个腌制文件时遇到一些问题,这个模块与我腌制该文件的模块不同。我知道以下线程:无法使用pickle和多文件模块加载文件。我已经尝试了将类导入模块的建议解决方案,在该模块中取消拾取文件,但它始终给我同样的错误:AttributeError: Can't get attribute 'Document' on

我要做的事情的基本结构:

pickles和unpickles对象的util文件,utils.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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方法的文件,class_def.py:

1
2
3
4
5
6
7
8
import utils

class Document(object):
    data =""

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

调用Load Util方法的文件,process.py:

1
2
3
4
import utils

if __name__ == '__main__':
     utils.load_document(file_path)

running process.py给出了所提到的attributeError。如果我将类def.py文件导入process.py并按照原始线程中所述运行它的主要方法,那么它可以工作,但是我希望能够单独运行这两个模块,因为类def文件是一个预处理步骤,需要相当长的时间。我怎么解决这个问题?


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

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

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

1
2
3
4
5
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运行,但这确实意味着数据将作为class_def.Document对象进行处理,因此加载它将从正确的位置检索类。否则,如果您有一种从另一个文档对象构造一个文档对象的方法,您可以在utils.py中这样做:

1
2
3
4
5
6
7
8
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)

虽然通常我更喜欢第一种方式。


我也遇到了类似的问题,只是认识到了我们实现之间的差异。

您的文件结构:

  • U.T.
    • 定义pickle函数
  • 等级等级
    • 进口用途
    • 定义类
    • 制作实例
    • 调用save pickle
  • Py
    • 进口用途
    • 负载酸洗

我的错误(使用你的文件名)首先是:

  • 实用程序u和u class.py
    • 定义类
    • 定义pickle函数
    • 制作实例
    • 调用save pickle
  • Py
    • 导入工具类
    • 调用加载pickle<

是什么解决了我的泡菜进口问题:

  • 实用程序u和u class.py
    • 定义类
    • 定义pickle函数
  • 泡菜
    • 导入工具类
    • 制作实例
    • 调用save pickle
  • Py
    • 调用加载pickle

这有一个很受欢迎的副作用,我不需要导入Util_和_类文件,因为它被烘焙到pickle文件中。调用实例并将pickle保存在单独的文件中,解决了__name__的问题"将pickled文件加载到与我对文件进行pickled的模块不同的模块中"。