python - boost python enable_pickling 期望

标签 python c++ boost pickle

嗨,我正在使用 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 a boost::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 the boost::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/

相关文章:

c++ - 在 PySide (Qt) 中打开另一个程序并在原始窗口中显示

c++ - 在 C++ 中清除空输入缓冲区的安全操作

c++ - mingw是否支持clr safe?

c++ - 在 Windows 运行时组件中使用 WRL 获取文件夹路径返回空字符串

c++ - 使用 boost 1.4.2 时命名空间前缺少 ';'

Python:如何深度复制字典列表

python - 将 json.dumps 转换为 Python 数据帧

python - 用excel/sql/pandas中同一列中出现的频率替换列中的值

c++ - "/usr/lib/libstdc .so.6: version ` GLIBCXX_3.4.1 5' not found"是什么意思,我该如何解决?

c++ - 带有插槽语义的超薄C++信号/事件机制