我有一个MyClass
定义在my_module
. MyClass
有一个方法pickle_myself
可以腌制相关类的实例:
def pickle_myself(self, pkl_file_path):
with open(pkl_file_path, 'w+') as f:
pkl.dump(self, f, protocol=2)
我已经确定my_module
在PYTHONPATH
. 在解释器中,执行__import__('my_module')
工作正常:
>>> __import__('my_module')
<module 'my_module' from 'A:\my_stuff\my_module.pyc'>
但是,当最终加载文件时,我得到:
File "A:\Anaconda\lib\pickle.py", line 1128, in find_class
__import__(module)
ImportError: No module named my_module
我已经确定的一些事情:
我没有更改
my_module.py
(更改模块目录后的 Python 酸洗)的位置我尝试
dill
改用,但仍然得到相同的错误(更多关于 python ImportError No module named)
编辑——重现错误的玩具示例:
该示例本身分布在一堆文件中。
首先,我们有模块ball
(存储在一个名为 的文件中ball.py
):
class Ball():
def __init__(self, ball_radius):
self.ball_radius = ball_radius
def say_hello(self):
print "Hi, I'm a ball with radius {}!".format(self.ball_radius)
然后,我们有模块test_environment
:
import os
import ball
#import dill as pkl
import pickle as pkl
class Environment():
def __init__(self, store_dir, num_balls, default_ball_radius):
self.store_dir = store_dir
self.balls_in_environment = [ball.Ball(default_ball_radius) for x in range(num_balls)]
def persist(self):
pkl_file_path = os.path.join(self.store_dir, "test_stored_env.pkl")
with open(pkl_file_path, 'w+') as f:
pkl.dump(self, f, protocol=2)
然后,我们有一个模块,它具有创建环境、持久化环境和加载环境的功能,称为make_persist_load
:
import os
import test_environment
#import pickle as pkl
import dill as pkl
def make_env_and_persist():
cwd = os.getcwd()
my_env = test_environment.Environment(cwd, 5, 5)
my_env.persist()
def load_env(store_path):
stored_env = None
with open(store_path, 'rb') as pkl_f:
stored_env = pkl.load(pkl_f)
return stored_env
然后我们有一个脚本把它们放在一起,在test_serialization.py
:
import os
import make_persist_load
MAKE_AND_PERSIST = True
LOAD = (not MAKE_AND_PERSIST)
cwd = os.getcwd()
store_path = os.path.join(cwd, "test_stored_env.pkl")
if MAKE_AND_PERSIST == True:
make_persist_load.make_env_and_persist()
if LOAD == True:
loaded_env = make_persist_load.load_env(store_path)
为了使这个玩具示例更易于使用,我将其全部放在一个 Github 存储库中,只需将其克隆到您选择的目录中即可。. 请参阅README
包含说明,我也在此处复制:
指示:
1)将存储库克隆到目录中。
2) 将存储库目录添加到 PYTHONPATH。
3) 打开test_serialization.py
,并将变量设置MAKE_AND_PERSIST
为True
。在解释器中运行脚本。
4) 关闭前一个解释器实例,并启动一个新实例。在test_serialization.py
,更改MAKE_AND_PERSIST
为False
,这将以编程方式设置LOAD
为True
。在解释器中运行脚本,导致ImportError: No module named test_environment
.
5) 默认情况下,测试设置为使用 dill,而不是 pickle。为了改变这一点,进入test_environment.py
和make_persist_load.py
,根据需要改变进口。
编辑:切换到莳萝'0.2.5.dev0'后,dill.detect.trace(True)
输出
C2: test_environment.Environment
# C2
D2: <dict object at 0x000000000A9BDAE8>
C2: ball.Ball
# C2
D2: <dict object at 0x000000000AA25048>
# D2
D2: <dict object at 0x000000000AA25268>
# D2
D2: <dict object at 0x000000000A9BD598>
# D2
D2: <dict object at 0x000000000A9BD9D8>
# D2
D2: <dict object at 0x000000000A9B0BF8>
# D2
# D2
编辑:玩具示例在 Mac/Ubuntu(即类 Unix 系统?)上运行时效果很好。它只在 Windows 上失败。