在不同文件中加载腌制对象 - 属性错误
Load pickled object in different file - Attribute error
我在将腌制文件加载到与我腌制文件所在的模块不同的模块中时遇到了一些问题。我知道以下线程:。我已经尝试了将 class 导入到我正在解压我的文件的模块中的建议解决方案,但它一直给我同样的错误:
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)
定义了 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 文件是一个预处理步骤,需要相当长的时间。我该如何解决这个问题?
在您的 class_def.py
文件中,您有以下代码:
if __name__ == '__main__':
doc = Document()
utils.save_document(doc)
这意味着 doc
将是一个 __main__.Document
对象,所以当它被 pickle 时,它期望能够从 main 中得到一个 Document
class模块,要解决此问题,您需要使用名为 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)
那样它需要 运行 class_def.py 文件两次,一次是 __main__
一次是 class_def
但这确实意味着数据将被 pickle作为 class_def.Document
对象,因此加载它将从正确的位置检索 class。否则,如果您有一种从另一个文档对象构造一个文档对象的方法,您可以在 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
- 定义 pickle 函数
- class_def.py
- 导入实用程序
- 定义class
- 创建实例
- 调用保存 pickle
- process.py
- 导入实用程序
- 加载 pickle
我的错误(使用你的文件名)首先是:
- util_and_class.py
- 定义class
- 定义 pickle 函数
- 创建实例
- 调用保存 pickle
- process.py
- 进口util_and_class
- 调用加载 pickle << 错误
是什么解决了我的 pickle 导入问题:
- util_and_class.py
- 定义class
- 定义 pickle 函数
- pickle_init.py
- 进口util_and_class
- 创建实例
- 调用保存 pickle
- process.py
- 调用负载 pickle
这有一个受欢迎的副作用,即我不需要导入 util_and_class 文件,因为它已烘焙到 pickle 文件中。调用实例并将 pickle 保存在单独的文件中解决了 "loading a pickled file in a module that is different from the module where I pickled the file."
的 __name__
问题
我在将腌制文件加载到与我腌制文件所在的模块不同的模块中时遇到了一些问题。我知道以下线程: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)
定义了 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 文件是一个预处理步骤,需要相当长的时间。我该如何解决这个问题?
在您的 class_def.py
文件中,您有以下代码:
if __name__ == '__main__':
doc = Document()
utils.save_document(doc)
这意味着 doc
将是一个 __main__.Document
对象,所以当它被 pickle 时,它期望能够从 main 中得到一个 Document
class模块,要解决此问题,您需要使用名为 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)
那样它需要 运行 class_def.py 文件两次,一次是 __main__
一次是 class_def
但这确实意味着数据将被 pickle作为 class_def.Document
对象,因此加载它将从正确的位置检索 class。否则,如果您有一种从另一个文档对象构造一个文档对象的方法,您可以在 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
- 定义 pickle 函数
- class_def.py
- 导入实用程序
- 定义class
- 创建实例
- 调用保存 pickle
- process.py
- 导入实用程序
- 加载 pickle
我的错误(使用你的文件名)首先是:
- util_and_class.py
- 定义class
- 定义 pickle 函数
- 创建实例
- 调用保存 pickle
- process.py
- 进口util_and_class
- 调用加载 pickle << 错误
是什么解决了我的 pickle 导入问题:
- util_and_class.py
- 定义class
- 定义 pickle 函数
- pickle_init.py
- 进口util_and_class
- 创建实例
- 调用保存 pickle
- process.py
- 调用负载 pickle
这有一个受欢迎的副作用,即我不需要导入 util_and_class 文件,因为它已烘焙到 pickle 文件中。调用实例并将 pickle 保存在单独的文件中解决了 "loading a pickled file in a module that is different from the module where I pickled the file."
的__name__
问题