当sys.path不同时,dill python模块是否处理导入模块?

当sys.path不同时,dill python模块是否处理导入模块?,python,dill,pathos,Python,Dill,Pathos,我正在评估dill,我想知道这个场景是否得到了处理。我有一个在python进程中成功导入模块的例子。我可以使用dill序列化该模块,然后将其加载到具有不同sys.path(不包括该模块)的不同进程中吗?现在我的导入失败了,但也许我做错了什么 这里有一个例子。我在foo.py模块的路径位于我的sys.path中的位置运行此脚本: % cat dill_dump.py import dill import foo myFile = "./foo.pkl" fh = open(myFile, 'wb

我正在评估dill,我想知道这个场景是否得到了处理。我有一个在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
回溯(最近一次呼叫最后一次):
文件“dill_load.py”,第4行,在
foo=静载荷(fh)
文件“/home/b/lib/python/dill-0.2.4-py2.6.egg/dill/dill.py”,第199行,装入
obj=pik.load()
文件“/rel/lang/python/2.6.4-8/lib/python2.6/pickle.py”,第858行,装入
调度[键](自身)
文件“/rel/lang/python/2.6.4-8/lib/python2.6/pickle.py”,第1133行,在load\u reduce中
值=func(*args)
文件“/home/b/lib/python/dill-0.2.4-py2.6.egg/dill/dill.py”,第678行,在导入模块中
返回\uuuu导入\uuuu(导入名称)
ImportError:没有名为foo的模块

因此,如果我需要在两个进程之间使用相同的python路径,那么序列化python模块有什么意义呢?或者换句话说,通过dill加载foo比只调用“import foo”有什么好处吗?

这是一个有趣的失败。请注意,如果您执行dill.dumps(foo)操作,您将获得模块的内容
foo
。失败的部分是使用python的内置导入挂钩(
\uuuuu import\uuu
)只需将模块注册到
sys.modules
)。应该可以解决这个问题,并修改
dill
,以便在PYTHONPATH中找不到模块时可以导入该模块。然而,我确实认为必须在PYTHONPATH中找到模块是正确的…这就是模块的期望…所以我不确定这是否是一个好主意。但可能是

如上所述,对于内容为:
hello=“hello world,I am foo”的文件
foo.py

您可以看到文件的内容保存在pickle中

dill
用于模块的主要原因是
dill
可以记录对模块的动态修改。例如,添加函数或其他对象:

>>> import foo 
>>> import dill
>>> foo.a = 100
>>> with open('foo.pkl', 'w') as f:
...   dill.dump(foo, f)
... 
>>> 
然后重新启动…(在PYTHONPATH中使用
foo


我将此添加为错误报告/功能请求:

关于如何实现此功能的一个建议是在序列化数据流中捕获sys.path,以便在加载时知道foo模块的位置。这将非常有用,因为它允许python状态具有更大的可移植性,您可以在具有不同设置的机器或shell上加载python会话。@BrentV:好主意。这些信息实际上应该在
\uuuu文件\uuuuu
属性中。所以
foo.\uuuuu文件\uuuuu
会告诉你它是从哪里加载的。当然,这只能在同一台计算机上使用,因此它不是一个完全可移植的解决方案。我使用
inspect
dill.source.getsource
捕获整个模块代码。
>>> import foo 
>>> import dill
>>> foo.a = 100
>>> with open('foo.pkl', 'w') as f:
...   dill.dump(foo, f)
... 
>>> 
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
>>>