ale*_*kuk 14 python swig pickle
我有一个Python的扩展模块,它使用SWIG作为包装器,我尝试用Pickle序列化它,我失败了=)
__reduce_ex__在我的C++代码中实现方法.有没有人有例子__reduce_ex__?有类似的Stackoverflow问题,但它省略了manager_constructor规范和实现.ale*_*kuk 14
好像我找到了适用于我的simlple解决方案:
所以,假设我们有C使用SWIG生成的类,然后我们用它包装
class PickalableC(C, PickalableSWIG):
def __init__(self, *args):
self.args = args
C.__init__(self)
Run Code Online (Sandbox Code Playgroud)
这里PickalableSWIG是
class PickalableSWIG:
def __setstate__(self, state):
self.__init__(*state['args'])
def __getstate__(self):
return {'args': self.args}
Run Code Online (Sandbox Code Playgroud)
然后
pickle.loads(pickle.dumps(C()))
Run Code Online (Sandbox Code Playgroud)
失败了,但是
pickle.loads(pickle.dumps(PickalableC()))
Run Code Online (Sandbox Code Playgroud)
成功=)
这里是一些其他方法。没有一个普遍接受的答案具有普遍适用性,但是如果您的班级满足一些(简单)要求,那么您可以通过实例化实例本身(而不是包装版本)来使用户的腌制更加容易。这些技术全部由LSST afw软件包使用。
请注意,使用__getstate__/ __setstate__对取消拾取时,不会调用该__init__方法,这意味着除非您小心,否则将有一个对象无法执行任何操作(如果继续获取,则有可能) 。这驱使我们使用(或您可以从致电)。NotImplementedError: Wrong number or type of arguments for overloaded function__reduce____init____setstate__
如果您是SWIG-ing类Foo,该类采用您可以从实例(例如,通过访问器)访问的构造函数参数,则将以下内容添加到您的接口(.i)文件中:
%extend Foo {
%pythoncode {
def __reduce__(self):
# Requires matching constructor: __init__(foo, bar)
args = self.getFoo(), self.getBar()
return self.__class__, args
}
}
Run Code Online (Sandbox Code Playgroud)
如果您可以使用默认构造函数创建对象,然后对其进行操作以恢复其以前的状态,请使用以下方法:
%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)
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您的班级可以对内存进行二进制数据的串行化处理(例如,您自己的磁盘格式的某些内存中表示形式):
%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)
}
Run Code Online (Sandbox Code Playgroud)
最后,如果您使用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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4549 次 |
| 最近记录: |