pickle,dill - ImportError:没有名为moduleS.module.module的模块

时间:2015-02-20 22:10:27

标签: python oop pickle dill

我在文件中遇到pickle.load()的问题。转储和加载在dill_read_write.py

中完成

dill_read_write.py

import os
import dill
from contact_geometry import ContactGeometry

def write_pickle(obj, filename):
    os.chdir(os.path.abspath(os.path.join(os.path.dirname(__file__))))
    filename = os.path.join(os.getcwd(), filename)
    with open(filename, 'wb') as output_:
        dill.dump(obj, output_)

def read_pickle(filename):
    with open(filename, 'rb') as input_:
        return dill.load(input_)

if __name__ == "__main__":
    read_pickle("ground_.pkl")

当PyQt应用程序(项目)运行时,将对象ContactGeometry数据保存到pickle文件。在write()中调用函数moduleC.py

moduleC.py

from contact_geometry import ContactGeometry
from moduleA.moduleB import dill_read_write

class Foo(FooItem):
    def __init__(self,...):
        ...
    def createGeometry(self):
        contact_geometry_ = ContactGeometry()
        #   save object to pickle file
        dill_read_write.write_pickle(contact_geometry_, "object_data.pkl") 

保存对象并创建pickle文件。但是,当我只运行文件dill_read_write.py从pickle文件读取(加载)对象数据时,我收到以下错误:

    Traceback (most recent call last):
File "C:\projectName\moduleA\moduleB\dill_read_write.py", line 29, in <module>
read("ground_.pkl")
File "C:\projectName\moduleA\moduleB\dill_read_write.py", line 24, in read
return dill.load(input_)
File "C:\Python27\lib\site-packages\dill-0.2.2-py2.7.egg\dill\dill.py", line 199, in load
obj = pik.load()
File "C:\Python27\Lib\pickle.py", line 858, in load
dispatch[key](self)
File "C:\Python27\Lib\pickle.py", line 1090, in load_global
klass = self.find_class(module, name)
File "C:\Python27\lib\site-packages\dill-0.2.2-py2.7.egg\dill\dill.py", line 278, in find_class
return StockUnpickler.find_class(self, module, name)
File "C:\Python27\Lib\pickle.py", line 1124, in find_class
__import__(module)
ImportError: No module named moduleA.moduleB.contact_geometry

我搜索了一下,发现dill可以比类pickle表现得更好,但我遇到了实施问题。我还发现我必须在文件__reduce__()的课程ContactGeometry中实施contact_geometry.py

contact_geometry.py

class ContactGeometry(object):
    def __init__(self, ...):
        ...    
    def __reduce__(self):
        return (self.__class__, (os.path.realpath(__file__))

但我不确定该方法应该返回什么?如何从当前情况成功加载pickle文件?

以下是项目结构,如果有任何帮助的话。

enter image description here

2 个答案:

答案 0 :(得分:3)

我是dill作者。很难说你是如​​何运行代码的,但看起来问题就是你运行代码和模块名称的一种方式,如@Antti Haapala的答案。他的建议也很好。

我将添加此内容...您需要确保(1)moduleA.moduleB.contact_geometry位于PYTHONPATH上,并且(2)您没有将模块转储为__main__.moduleB.contact_geometry并尝试将其加载为moduleA.moduleB.contact_geometry - dill__main__视为模块(大部分)。

但是,您不需要在类中添加__reduce__方法。

答案 1 :(得分:1)

你不能在这样的包中运行python文件;它不会找到顶级包名称。我建议以下任何一项:

  1. 在顶级(main.py所在的位置)编写一个启动脚本,从read_write_dill

  2. 导入并运行moduleA.moduleB
  3. 而是在main所在的顶级目录中,您可以运行 该模块包含python -m moduleA.moduleB.dill_read_write

  4. 或者,我的首选替代方案是为您的项目编写setup.py并为该实用程序编写script