嗨,我正在使用 python 启动一个 cpp 类,该类使用 boost python lib 转换为可用的 python。同时,我需要pickle使用启用python的cpp类的python类。
所以我所做的是将enable_picking()添加到示例类定义中,如下所示:
class_<pform::base::Price>("Price", init<double>())
.def(self == self)
.def(self_ns::str(self_ns::self)) // __str__
.def("get_value", &pform::base::Price::get_value)
它使类变得可 pickle 。但是,当我解封它时,我收到此错误。
Boost.Python.ArgumentError: Python argument types in
Price.__init__(Price)
did not match C++ signature:
__init__(_object*, double)
那么这里缺少什么?
最佳答案
有点晚了,但我找到了相关的 boost 文档:
http://www.boost.org/doc/libs/1_64_0/libs/python/doc/html/reference/topics/pickle_support.html
The Pickle Interface
At the user level, the Boost.Python pickle interface involves three special methods:
__getinitargs__
When an instance of a Boost.Python extension class is pickled, the pickler tests if the instance has a__getinitargs__
method. This method must return a Python tuple (it is most convenient to use aboost::python::tuple
). When the instance is restored by the unpickler, the contents of this tuple are used as the arguments for the class constructor. If__getinitargs__
is not defined, pickle.load will call the constructor (__init__
) without arguments; i.e., the object must be default-constructible.
__getstate__
When an instance of a Boost.Python extension class is pickled, the pickler tests if the instance has a__getstate__
method. This method should return a Python object representing the state of the instance.
__setstate__
When an instance of a Boost.Python extension class is restored by the unpickler (pickle.load), it is first constructed using the result of__getinitargs__
as arguments (see above). Subsequently the unpickler tests if the new instance has a__setstate__
method. If so, this method is called with the result of__getstate__
(a Python object) as the argument.The three special methods described above may be
.def()
'ed individually by the user. However, Boost.Python provides an easy to use high-level interface via theboost::python::pickle_suite
class that also enforces consistency:__getstate__
and__setstate__
must be defined as pairs. Use of this interface is demonstrated by the following examples.
在您的特定示例中,该类不可默认构造,因为它需要一个 double 参数(我假设它是“值”)。要将其包装为 Python,您还需要定义:
.def("__getinitargs__", +[](pform::base::Price const& self){
return boost::python::make_tuple(self.get_value());
})
现在 Boost Python 将使用“value”初始化你的类;而不是调用默认构造函数 (pform::base::Price()
)。
关于python - boost python enable_pickling 期望,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41739456/