如何使用pybind11将采用模板方法模式和虚拟接口的C++类导出到Python世界?

huangapple go评论64阅读模式
英文:

How to export c++ class adopted template method pattern with virtual interface to python world by pybind11?

问题

We have a class hierarchy which follows the template method pattern. The Interface class has a pure virtual method process(). The AbstractImpl class inherits it and fills the process body with some pure virtual stepX methods. Finally, the derived class Concrete1 implements those stepX methods to extend custom behaviors.

In the C++ world, you can easily use it like:

Interface* obj = new Derived();
int res = obj->process();

Now, we need to create some Python bindings for the Derived class for some scaffolding test usage by pybind11. Ideally, in the Python world, we could write:

obj = Derived()
res = obj.process()

I've checked the pybind11 documentation's class section, which provides some examples like PYBIND11_OVERRIDE_PURE.

However, the Derived class is not derived directly from the Interface class, and we only want to export the base process method but not the other protected step methods to the Python world.

I wonder if there's any way to export the Derived class and its public interface process to the Python world without adding much intrusive code like PYBIND11_OVERRIDE_PURE.

英文:

We have a class hierarchy which follow the template method pattern. The Interface class has a pure virtual method process(). class AbstractImpl inherit it and fill the process body with some pure virtual stepX method. Finally, derived class Concrete1 implement those stepX method to extend custom behaviors.

class Interface {
public:
   virtual int process() = 0;
};

class AbstractImpl : public Interface {
public:
   int process override(){
       step1();
       // do something
       step2();
   }
protected:
    virtual void step1() = 0;
    virtual void step2() = 0;
};

class Derived : public AbstractImpl {
protected:
    void step1() final {
        // do something
    }

    void step2() final {
        // do something
    }
};

In c++ world, i can use easily it like:

Interface* obj = new Derived();
int res = obj->process();

Now we need to create some python binding for Derived class for some scaffolding test usage by pybind11. Ideally, in python world we could write:

obj = Derived()
res = obj.process()

I've checked the pybind11 document class section, which provide some examples like PYBIND11_OVERRIDE_PURE.

However, the Derived class actually not derived directly from Interface class, and we only want to export the base process method but not other protected step method to python world.

I wonder is there anyway to export the Derived class and it public interface process to python world, without much instruive code like PYBIND11_OVERRIDE_PURE added?

答案1

得分: 1

以下是您要翻译的部分:

如果您只想在您的Python代码中像这样使用您的Derived类:

obj = Derived()
res = obj.process()

只需将其导出到Python作为Derived类,具有AbstractImpl父类和仅一个方法process即可:

PYBIND11_MODULE(examplePythonModule, m) {
    py::class_<AbstractImpl>(m, "AbstractImpl")
        // 无法对抽象类进行init
        .def("process", &AbstractImpl::process);
    py::class_<Derived, AbstractImpl>(m, "Derived")
        .def(py::init<>());
        // 过程方法已经由父类导出
}

添加一些可观察的行为并检查它是否有效。只要不导出接受Interface&作为参数的任何函数,Python甚至不需要知道这种类型。

英文:

If you only want to use your Derived class in your python code like this

obj = Derived()
res = obj.process()

it is just enough to export it to python as Derived class with AbstractImpl parent class and only one method process:

PYBIND11_MODULE(examplePythonModule, m) {
    py::class_&lt;AbstractImpl&gt;(m, &quot;AbstractImpl&quot;)
        // no &quot;init&quot; for abstract class
        .def(&quot;process&quot;, &amp;AbstractImpl::process);
    py::class_&lt;Derived, AbstractImpl&gt;(m, &quot;Derived&quot;)
        .def(py::init&lt;&gt;());
        // process method already exported by the parent class
}

Add some observable behavior and check that it works. As long as you don't export any functions taking Interface&amp; as argument, python doesn't even need to know about this type.

huangapple
  • 本文由 发表于 2023年4月13日 21:28:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76006023.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定