pickle 无法导入已存在的模块?

9
为什么会发生这种情况?
import window; print "LOADED"; data = cPickle.loads(data)

结果如下:
LOADED
Traceback (most recent call last):
...
    import window; print "LOADED"; data = cPickle.loads(data)
exceptions.ImportError: No module named window

如果我使用import window导入模块,它可以正常加载,但是使用cPickle加载时似乎无法工作。

以下是一些可能相关的附加信息:

我保存文件的模块位于project1\MODULE\submodule\main.py中。 window 模块位于project1\MODULE\window.py中。 main.py 开始如下:

import sys
sys.path.append("..\\..")
sys.path.append("..")
...
import window

我正在尝试加载的模块位于project2\project2sub\MODULE\data.py中,不会干扰sys路径。
在两种情况下,MODULE是相同的:我想要加载的模块是project2\project2sub\MODULE\window.pysys.path附加会影响到这个吗?

“data” 中包含了什么?正在被 pickled 的是什么? - Andrew
2个回答

11

Pickle依赖于模块路径。无论你如何加载模块,只要不混乱sys.path,pickle的读取和保存都应该可以正常工作。然而,如果你在一个地方使用import module.foo,并且在另一个地方使用sys.path.append('module'); import foo,那么你就有了两个不同的模块路径:在第一种情况下,模块路径是module.foo,而在第二种情况下,它只是foo。这些是不等价的,这会阻止pickle正常工作。


哇,你的解释解决了我一个持续了一周的问题。我的错误正是你所描述的那个。尽管我在子文件夹下有__init__文件,但我仍然无法导入这些文件。然后我尝试了sys.path.append的解决方案。结果,它引起了更大的问题!非常感谢你。 - Kubra Altun

6

请检查在保存程序中导入类的方式是否与加载程序中相同。

加载:

 import window
 myObj.window_obj = window.wObj

加载中

 import window
 myObj = cPickle.loads(data)

注意:

保存:

 from window import wObj
 myObj.window_obj = wObj

加载中:

 import window
 myObj = cPickle.loads(data)

我有一种感觉,这两个都可以工作。我认为问题在于一个中我做了 import module.foo(实际上)。而在另一个中,我做了 sys.path.append('module'); import foo(实际上)。因此路径不同(foo vs. module/foo),这就搞砸了。 - Claudiu
@Claudiu: 我也遇到了同样的问题(并找到了解决方案),你能把这个发表为答案并接受吗?(这样其他人就可以找到) - Frames Catherine White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接