我對Python的使用SWIG作爲包裝的擴展模塊,我嘗試用泡椒序列化它,我不=)如何使我的SWIG擴展模塊與Pickle一起工作?
- 如果任何人有SWIG擴展,可醃漬的來源,會喜歡看見!
- 看來我應該在我的C++代碼中實現
__reduce_ex__
方法。有沒有人有__reduce_ex__
的例子? There is similar Stackoverflow question但它省略了manager_constructor
規範和實現。
我對Python的使用SWIG作爲包裝的擴展模塊,我嘗試用泡椒序列化它,我不=)如何使我的SWIG擴展模塊與Pickle一起工作?
__reduce_ex__
方法。有沒有人有__reduce_ex__
的例子? There is similar Stackoverflow question但它省略了manager_constructor
規範和實現。好像我發現,我的作品simlple解決方案:
所以我們可以說,我們有一個與SWIG生成的類C
,那麼我們用
class PickalableC(C, PickalableSWIG):
def __init__(self, *args):
self.args = args
C.__init__(self)
把它包在那裏PickalableSWIG
是
class PickalableSWIG:
def __setstate__(self, state):
self.__init__(*state['args'])
def __getstate__(self):
return {'args': self.args}
然後
pickle.loads(pickle.dumps(C()))
失敗,但
pickle.loads(pickle.dumps(PickalableC()))
成功=)
這裏有一些額外的方法。沒有一個像accepted answer一樣具有普遍適用性,但是如果您的課程符合一些(簡單)要求,那麼您可以通過使實例本身(不包裝版本)可供選擇來讓用戶更輕鬆地進行酸洗。這些技術全部由LSST afw package使用。
注意使用__getstate__
/__setstate__
對取儲存時,該__init__
方法不被調用,這意味着,除非你很小心,你就會有一個對象,你不能做任何事情(如果你不斷得到NotImplementedError: Wrong number or type of arguments for overloaded function
,這是一種可能性)。這使我們使用__reduce__
(或者您可以從__setstate__
調用__init__
)。
如果你痛飲-ING類Foo
這需要你有從實例訪問構造函數的參數(例如,通過存取),以下內容添加到您的接口(.i
)文件:
%extend Foo {
%pythoncode {
def __reduce__(self):
# Requires matching constructor: __init__(foo, bar)
args = self.getFoo(), self.getBar()
return self.__class__, args
}
}
如果你可以用默認的構造函數創建對象,然後操縱它來恢復以前的狀態,使用這樣的:
%extend Foo {
%pythoncode {
def __getstate__(self):
args = self.getFoo(), self.getBar()
return args
def __setstate__(self, state):
# Requires empty constructor: __init__()
self.__init__()
foo, bar = state
self.setFoo(foo)
self.setBar(bar)
}
}
另外,如果你的類可以做從內存中的二進制數據/的序列化(例如, ,你自己的磁盤格式的一些內存中表示):
%include "cdata.i"
%extend Foo {
%pythoncode {
def __reduce__(self):
s = Serializer()
self.serialize(s)
size = s.getLength()
data = cdata(s.getData(), size)
return unreduceFoo, (data, size)
}
}
%pythoncode {
def unreduceFoo(data, size):
s = Serializer(size)
memmove(s.getData(), data)
return Foo(s)
}
最後,如果你使用boost::serialization
,通過Sogo Mineo使用這個片斷:
%{
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <sstream>
%}
%include "std_string.i"
%define %boost_picklable(cls...)
%extend cls {
std::string __getstate__()
{
std::stringstream ss;
boost::archive::binary_oarchive ar(ss);
ar << *($self);
return ss.str();
}
void __setstate_internal(std::string const& sState)
{
std::stringstream ss(sState);
boost::archive::binary_iarchive ar(ss);
ar >> *($self);
}
%pythoncode %{
def __setstate__(self, sState):
self.__init__()
self.__setstate_internal(sState)
%}
}
%enddef
%boost_picklable(Foo)
也許元類可以用這裏。 – alexanderkuk 2012-02-22 15:18:22
如果有人對使用mpi4py進行並行評估感興趣,我需要另外實現建議的解決方案[這裏](http://stackoverflow.com/questions/1816958/cant-pickle-type-instancemethod-when-using-pythons- multiprocessing-pool-ma)讓它與(包裝)類的實例方法一起工作 – 2013-09-02 14:45:58
@FredSchoen:'dill'串行器可以與'mpi4py'一起使用。只需將序列化程序設置爲'dill'而不是'pickle'。請參閱:http://stackoverflow.com/questions/21779541/mpi4py-replace-built-in-serialization – 2015-03-18 17:10:21