英文:
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_<AbstractImpl>(m, "AbstractImpl")
// no "init" for abstract class
.def("process", &AbstractImpl::process);
py::class_<Derived, AbstractImpl>(m, "Derived")
.def(py::init<>());
// 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&
as argument, python doesn't even need to know about this type.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论