问题描述
// C ++ A级 {
public:
A() {};
virtual int override_me(int a) {return 2*a;};
int calculate(int a) { return this->override_me(a) ;}
};
我想做的是使用Boost.python将此类公开给Python,从Python中的此类继承,并具有正确的覆盖名称:
#python:
class B(A):
def override_me(self,a):
return 5*a
b = B()
b.calculate(1) # should return 5 instead of 2
我想对纯虚函数做同样的事情。我正在寻找一种不在类A上用C ++创建任何包装类的方法。这有可能吗?如果是/否,我该怎么办?
解决方法
您可以在类周围提供一个精简包装,将override_me
方法调用委托给特定于boost::python
的重写函数。
派生类calculate
的调用只需调用父类calculate
的方法,因此从Python调用它们时,它们将调用C ++定义的calculate
方法,但仍允许{{1} }方法要从Python覆盖:
override_me
g ++ virtual_override.cpp -fPIC -shared -I / path / to / include / python3 -L / path / to / libpython3 -o my_lib.so -lpython3 -lboost_python3
示例:
这允许非纯粹的情况,例如,当不重写override_me时,默认函数称为:
#include <boost/python.hpp>
using namespace boost;
using namespace boost::python;
class A {
public:
A() {};
virtual int override_me(int a) {
return 2*a;
};
virtual int calculate(int a) {
return this->override_me(a);
}
};
struct AWrap: A,public boost::python::wrapper<A> {
AWrap() : A() {};
int override_me(int a) override {
if (override f = this->get_override("override_me")) {
return this->get_override("override_me")(a);
} else {
return A::override_me(a);
}
};
int calculate(int a) override {
return A::calculate(a);
}
};
BOOST_PYTHON_MODULE(my_lib)
{
python::class_<AWrap,boost::noncopyable>("A",python::init<>())
.def("override_me",&AWrap::override_me)
.def("calculate",&AWrap::calculate);
}
int main() {}
2
但是可以从Python中进行虚拟覆盖:
import my_lib
class B(my_lib.A):
pass
b = B()
print (b.calculate(1))
5