【发布时间】:2016-03-02 07:45:01
【问题描述】:
我在my_module 中定义了一个类MyClass。 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 pickling after changing a module's directory)我已尝试改用
dill,但仍然出现相同的错误 (More on python ImportError No module named)
EDIT -- 重现错误的玩具示例:
示例本身分布在一堆文件中。
首先,我们有模块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)
为了便于使用这个玩具示例,I have put it all up on in a Github repository that simply needs to be cloned into your directory of choice.。请参阅包含说明的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,根据需要改变导入。
编辑:切换到 dill '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 上失败。
【问题讨论】:
-
我猜
__import__('my_module')在您的当前目录中工作。可以用绝对路径测试看看是否遇到同样的问题吗? -
你如何“最终加载文件”?
-
我克隆了,按照步骤操作,它对我有用。我不知道在解释器中运行脚本是什么意思,所以我只是做了
python testing_serialization.py。 -
我还按照上面发布的文件执行了步骤 2-5。它对我有用(我在两个文件中都使用了
import dill as pkl)。那么……你有什么版本的dill? (我用的是master,来自github)……你有什么版本的python? (我使用的是 2.7)……你有什么操作系统? (我在 MacOSX 上)……你是从 '.' 运行的吗? (我一直都是)...您是否在运行之间删除所有内容(.pyc,.pkl,...)?您是否在dump运行和load之间更改目录? -
@MikeMcKerns (1)
dill version: dill.info.this_version: 0.2.4,(2) Python 版本:Python 2.7.10,3) 操作系统:Windows 10 专业版,(3) 我不确定从 '.' 运行什么意思是——你的意思是test_serialization.py与模块在同一目录中,ball、test_environment等?在那种情况下,是的,我从'。 (4) 我没有在运行之间删除所有内容,但我刚刚尝试过,没有任何区别,(5) 我没有更改test_serialization.py所在的目录存储在两次运行之间(不确定是否正确解释问题)
标签: python windows pickle dill