我正在评估莳萝,我想知道是否处理了这种情况。我有一个案例,我成功导入python进程中的模块。我可以使用dill进行序列化,然后将该模块加载到具有不同sys.path并且不包含该模块的其他进程中吗?现在我得到导入失败,但也许我做错了。
这是一个例子。我运行这个脚本,其中foo.py模块的路径在我的sys.path中:
% cat dill_dump.py
import dill
import foo
myFile = "./foo.pkl"
fh = open(myFile, 'wb')
dill.dump(foo, fh)
现在,我运行这个脚本,我的PYTHONPATH中没有foo.py的目录:
% cat dill_load.py
import dill
myFile = "./foo.pkl"
fh = open(myFile, 'rb')
foo = dill.load(fh)
print foo
这个堆栈跟踪失败了:
Traceback (most recent call last):
File "dill_load.py", line 4, in <module>
foo = dill.load(fh)
File "/home/b/lib/python/dill-0.2.4-py2.6.egg/dill/dill.py", line 199, in load
obj = pik.load()
File "/rel/lang/python/2.6.4-8/lib/python2.6/pickle.py", line 858, in load
dispatch[key](self)
File "/rel/lang/python/2.6.4-8/lib/python2.6/pickle.py", line 1133, in load_reduce
value = func(*args)
File "/home/b/lib/python/dill-0.2.4-py2.6.egg/dill/dill.py", line 678, in _import_module
return __import__(import_name)
ImportError: No module named foo
所以,如果我需要在两个进程之间使用相同的python路径,那么序列化python模块的重点是什么?或者换句话说,通过莳萝加载foo是否有任何优势只需要一个&#34; import foo&#34;调用
答案 0 :(得分:0)
这是一个有趣的失败。请注意,如果你执行dill.dumps(foo)
,你将获得模块foo
的内容...失败的部分是使用python的内置导入钩子(__import__
)来做更多的事情来注册将模块转换为sys.modules
。应该可以解决这个问题并修改dill
,以便在PYTHONPATH中找不到模块时可以导入模块。但是,我认为必须在PYTHONPATH中找到该模块是正确的......这就是对模块的期望......所以我不确定这是不是一个好主意。但它可能是......
如上所述,对于文件foo.py
,内容为:hello = "hello world, I am foo"
>>> import dill
>>> import foo
>>> dill.dumps(foo)
'\x80\x02cdill.dill\n_import_module\nq\x00U\x03fooq\x01\x85q\x02Rq\x03}q\x04(U\x08__name__q\x05h\x01U\x08__file__q\x06U\x06foo.pyq\x07U\x05helloq\x08U\x15hello world, I am fooq\tU\x07__doc__q\nNU\x0b__package__q\x0bNub.'
您可以看到文件的内容保留在pickle中。
将dill
与模块一起使用的主要原因是dill
可以记录对模块的动态修改。例如,添加函数或其他对象:
>>> import foo
>>> import dill
>>> foo.a = 100
>>> with open('foo.pkl', 'w') as f:
... dill.dump(foo, f)
...
>>>
然后重新开始......(在PYTHONPATH中使用foo
)
Python 2.7.10 (default, May 25 2015, 13:16:30)
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> with open('foo.pkl', 'r') as f:
... foo = dill.load(f)
...
>>> foo.hello
'hello world, I am foo'
>>> foo.a
100
>>>
我已将此添加为错误报告/功能请求:https://github.com/uqfoundation/dill/issues/123