2

下面的工作示例将由 float 和 int64_t 组成的变体类型向量返回给 Python。目的(由注释的代码行说明**)是通过启用用 C++ 构建的 Decimal(python 类)以相同的结构传递回 Python 来为此添加更多功能。

#include <pybind11/pybind11.h>
#include <vector>
#include <variant>
#include <string>
#include <pybind11/stl.h>
#include <pybind11/complex.h>
#include <pybind11/functional.h>
#include <pybind11/chrono.h>
namespace py = pybind11;

// Importing Decimal class, as shown here
// https://pybind11.readthedocs.io/en/stable/advanced/pycpp/object.html?highlight=Decimal(#accessing-python-libraries-from-c
py::object Decimal = py::module_::import("decimal").attr("Decimal");

//typedef std::variant<float, int64_t, Decimal> Listtypes;  // **
typedef std::variant<float, int64_t> Listtypes;

std::vector<ListTypes> returnList() {

    std::vector<ListTypes> list(3);
    
    int64_t integerVal = 987654321;
    float floatVal = 1.01;

    // Constructing python object, as shown here 
   //https://pybind11.readthedocs.io/en/stable/advanced/pycpp/object.html#callingpythonfunctions
    py::object pi = Decimal("3.14159");
    
    list[0] = integerVal;
    list[1] = floatVal;
    //list[2] = pi;        // **

    return list;
}

PYBIND11_MODULE(pBind, m) {
    m.def("returnList", &returnList, "Function to return list of differing types");
}

所以要解决这个问题,可以将 Decimal 表示为 std::variant 的一部分,以便可以将它与向量一起传递回 Python,还是解决方案不那么简单?

4

1 回答 1

1

您不能只将pi变量按原样添加到std::variant向量中,因为它的类型是py::object. 您可以将其添加到您的ListTypes所以只需更改行

typedef std::variant<float, int64_t, py::object> Listtypes;

但是你在 Python 端的列表将是[987654321, 1.0099999904632568, Decimal(3.14159)]

我认为您宁愿使用pybind 提供的转换将pi变量转换为浮点数,以便您的代码变为

#include <pybind11/pybind11.h>
#include <vector>
#include <variant>
#include <string>
#include <pybind11/stl.h>
#include <pybind11/complex.h>
#include <pybind11/functional.h>
#include <pybind11/chrono.h>
namespace py = pybind11;

// Importing Decimal class, as shown here
// https://pybind11.readthedocs.io/en/stable/advanced/pycpp/object.html?highlight=Decimal(#accessing-python-libraries-from-c
py::object Decimal = py::module_::import("decimal").attr("Decimal");

//typedef std::variant<float, int64_t, Decimal> Listtypes;  // **
typedef std::variant<float, int64_t> Listtypes;

std::vector<ListTypes> returnList() {

    std::vector<ListTypes> list(3);
    
    int64_t integerVal = 987654321;
    float floatVal = 1.01;

    // Constructing python object, as shown here 
   //https://pybind11.readthedocs.io/en/stable/advanced/pycpp/object.html#callingpythonfunctions
    py::object pi = Decimal("3.14159");
    
    list[0] = integerVal;
    list[1] = floatVal;
    list[2] = pi.cast<float>();        // we cast to float

    return list;
}

PYBIND11_MODULE(pBind, m) {
    m.def("returnList", &returnList, "Function to return list of differing types");
}
于 2020-12-14T20:25:36.383 回答