如何在C ++中将pybind11中的新属性设置为python对象?

时间:2019-11-06 22:34:33

标签: python c++ pybind11

我正在尝试使用pybind11在c ++中创建一个新的python类,用数据填充它,然后返回它。

例如,使用python中的一个简单类,然后将其用于用pybind11编译的c ++函数调用中。

from TEST import func_wrapper 

class class_DATA_py:
    def __init__(self):
        self.a   = 1

data_class_input = class_DATA_py()
data_return      = func_wrapper(data_class_input) #is not compiling
print(data_return.new_data) #is what I wish to see

现在借助pybind 11使用c ++中的类。

#include <pybind11/pybind11.h>
namespace py = pybind11;

py::object func_wrapper(py::object data_class_input){

    //1) read in the data of some python class
    int a       = data_class_input.attr("a").cast<int>();  

    //2) do something 
    float new_data = 3.1; //just an example value

    //3) make the results accessible from python:
    py::object data_class_output;
    //This is where things go wrong and crashes during compilation
    //Is there a way to set an attribute so that I can write something like below?
    data_class_output.attr("new_data")    = py::cast(new_data);
    return data_class_output;
}

//pybind11-related:
PYBIND11_MODULE(TEST,m){
  m.doc() = "pybind11 example plugin";
  m.def("func_wrapper",  &func_wrapper);
  );

然后的想法是能够使用python中的data_class_output并访问例如data_class_output.new_data值。

一种解决方法是也在python中定义data_class_output类,将其用作附加输入,然后在其中填充值。

但是,是否可以按照上述方法工作并在c ++中从头开始定义“ py :: object data_class_output”,然后在python中使用它而没有问题?

1 个答案:

答案 0 :(得分:0)

需要有一些对象实例来将新属性附加到该实例。如果需要一个新对象,则需要使用某种类型的对象来创建。如果基于上面的讨论,您希望输出类型和输入类型相同,则可以从输入的__class__属性中获取正确的类型。然后,假设__init__不使用任何其他参数,请创建一个实例并附加该属性。

通过调整您的工作示例,如下所示:

#include <pybind11/pybind11.h>

namespace py = pybind11;

py::object func_wrapper(py::object data_class_input){

    //1) read in the data of some python class
    int a       = data_class_input.attr("a").cast<int>();

    //2) do something
    float new_data = 3.1; //just an example value

    //3) make the results accessible from python:
    py::object data_class_input_type = data_class_input.attr("__class__");
    py::object data_class_output = data_class_input_type();
    data_class_output.attr("new_data")    = py::cast(new_data);

    return data_class_output;
}

//pybind11-related:
PYBIND11_MODULE(TEST,m){
  m.doc() = "pybind11 example plugin";
  m.def("func_wrapper",  &func_wrapper);
}

之后将打印您的python代码段:

3.09999990463