Pybind11:使用 lambda 初始化 <>

Pybind11: init<> with lambda

我使用 pybind11 作为我的 C++ 代码到 python 库的包装器。

碰巧有些参数我无法提供,或者有时我想做一个我在 C++ 方面知道的 conversion/initialization。例如,这可能是因为 class 在 python 中未知。那怎么可能呢?到目前为止,我看到的唯一 "solution" 是在 C++ 中创建继承代理 class。

例子:我想define/bind一个pythonclass一个:

class A:
  def __init__(self, B b):
    ...

使用 C++ 等价物 class:

class A {
  A(C c, D d);
}

我可以为 pybind11::init<> 创建某种 lambda 或等效项吗?

pybind11 允许您将工厂函数绑定为 init 方法。因此,您必须在 C++ 中提供一个函数,该函数采用 B 和 return A,然后您可以将其绑定为 A 的初始化方法。

pybind11 文档中的示例

class Example {
private:
    Example(int); // private constructor
public:
    // Factory function:
    static Example create(int a) { return Example(a); }
};

py::class_<Example>(m, "Example")
    .def(py::init(&Example::create));

如果您不想(或不能)更改 class C++ 中的 A,您也应该能够绑定自由函数(不仅仅是静态函数)。

所以它可能看起来像这样(更改为 return a unique_ptr,pybind 可以直接取得原始实例的所有权。但两者都应该有效)

std::unique_ptr<A> createA(const B& arg)
{
  // returns an instance of A that you made using B
}

py::class_<A>(m, "A")
    .def(py::init(&createA));

您显然还必须为 python 中的 B 提供绑定。

这里有文档并包含更多示例,包括如何执行 init lambda: https://pybind11.readthedocs.io/en/stable/advanced/classes.html#custom-constructors