Pickle转储引用模块的对象

时间:2015-08-11 23:55:34

标签: python module pickle

我想像这样挑选一个对象:

import module_A
import module_B

class SomeClass(object):
  def __init__(self, the_module):
    self.module = the_module
    self.some_other_members = whatever

x = SomeClass(module_A)

不允许,错误是我无法转储模块。在这种情况下,我对实际转储模块不感兴趣。但是,对象使用哪个模块很重要。所以我想转储模块的一些标识符,以便在__setstate__上我可以将self.module指向正确的模块。我应该使用哪种标识符,以便在__setstate__上我可以通过该标识符找到正确的模块?可能有许多可能的模块,类SomeClass现在知道它们中的哪一个。

更新:

很抱歉,我们发现的错误消息是我们使用cPickle时的错误消息。普通的pickle没有这个问题,正如迈克所说,dill也支持酸洗模块。我正在使用的最终解决方案是:https://mail.python.org/pipermail/python-ideas/2013-July/021959.html

2 个答案:

答案 0 :(得分:0)

嗯,几乎不是一个完整的答案,但是当我看到一个模块,我设置了一个虚拟的'一个测试对象,我得到了。

print dummy.module.__file__

输出

'lib/utils.pyc'

和一些检查:

>>> type(dummy.module)
<type 'module'>
>>> type(dummy.module.__file__)
<type 'str'>
>>>

也许你可以保存&#34; lib / utils&#34;从上面(在__getstate__期间),然后执行相应的导入咒语,以便在__setstate __期间恢复模块?

如果模块已经加载,你根本不必费心去使用 import

dummy.module2 = sys.modules["lib.utils"]

答案 1 :(得分:0)

我认为您可以使用dill完全按照您的要求进行操作,这提供了比pickle更好的序列化。

>>> import dill
>>> import numpy
>>>
>>> import math
>>> 
>>> class SomeClass(object):
...   def __init__(self, module):
...     self.module = module
...     self.other = lambda x: numpy.arange(3)
... 
>>> # save the class instance
>>> x = SomeClass(math)
>>> _x = dill.dumps(x)
>>>
>>> # delete a bunch of stuff
>>> del SomeClass 
>>> del math
>>> import sys
>>> del sys.modules['math']
>>> del x
>>>
>>> # unpickle
>>> x = dill.loads(_x)
>>> x.module
>>> x.module.sin(x.other(0)[0])
0.0