Pickle 转储引用模块的对象
Pickle dump an object referencing a module
我想 pickle-dump 这样的对象:
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__
上通过该标识符找到正确的模块?可能有很多可能的模块,class SomeClass
现在知道其中有哪些。
更新:
抱歉,我们在使用 cPickle
时发现错误消息。普通的 pickle
没有这个问题,而且正如 Mike 所说, dill
也支持 pickling 模块。我使用的最终解决方案是此处给出的解决方案:https://mail.python.org/pipermail/python-ideas/2013-July/021959.html.
好吧,这不是一个完整的答案,但是当我查看我在 'dummy' 上设置的模块时,一个测试对象,我得到了。
print dummy.module.__file__
输出
'lib/utils.pyc'
和一些检查:
>>> type(dummy.module)
<type 'module'>
>>> type(dummy.module.__file__)
<type 'str'>
>>>
也许你可以从上面保存 "lib/utils"(在你的 __getstate__ 期间),然后执行适当的 import 咒语以在 __setstate__?
如果模块已经加载,您根本不必为 import 操心:
dummy.module2 = sys.modules["lib.utils"]
我认为您可以使用 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
我想 pickle-dump 这样的对象:
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__
上通过该标识符找到正确的模块?可能有很多可能的模块,class SomeClass
现在知道其中有哪些。
更新:
抱歉,我们在使用 cPickle
时发现错误消息。普通的 pickle
没有这个问题,而且正如 Mike 所说, dill
也支持 pickling 模块。我使用的最终解决方案是此处给出的解决方案:https://mail.python.org/pipermail/python-ideas/2013-July/021959.html.
好吧,这不是一个完整的答案,但是当我查看我在 'dummy' 上设置的模块时,一个测试对象,我得到了。
print dummy.module.__file__
输出
'lib/utils.pyc'
和一些检查:
>>> type(dummy.module)
<type 'module'>
>>> type(dummy.module.__file__)
<type 'str'>
>>>
也许你可以从上面保存 "lib/utils"(在你的 __getstate__ 期间),然后执行适当的 import 咒语以在 __setstate__?
如果模块已经加载,您根本不必为 import 操心:
dummy.module2 = sys.modules["lib.utils"]
我认为您可以使用 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