用 Boost.python 覆盖 Python 中的 C++ 虚函数?
override a C++ virtual function within Python with Boost.python?
我有一个带有虚拟方法的 C++ class:
//C++
class一个
{
public:
A() {};
virtual int override_me(int a) {return 2*a;};
int calculate(int a) { return this->override_me(a) ;}
};
我想做的是用 Boost.python 将此 class 公开给 Python,从 Python 中的此 class 继承并拥有正确覆盖调用:
#python:
class B(A):
def override_me(self, a):
return 5*a
b = B()
b.calculate(1) # should return 5 instead of 2
我想对纯虚函数做同样的事情。我正在寻找一种不在 class A 上用 C++ 创建任何包装器 class 的方法。这可能吗?如果是/如果不是,我该怎么做?
您可以在 class 周围提供一个精简包装器,将 override_me
方法调用委托给 boost::python
特定的覆盖函数。
派生的 class calculate
调用简单地调用父 class calculate
方法,所以当它们从 Python 调用时,它们调用 C++ 定义的calculate
方法,但仍允许从 Python:
覆盖 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() {}
g++ virtual_override.cpp -fPIC -shared -I/path/to/include/python3 -L/path/to/libpython3 -o my_lib.so -lpython3 -lboost_python3
示例:
这允许 non-pure 情况,例如,当 override_me 未被覆盖时,默认函数被调用:
import my_lib
class B(my_lib.A):
pass
b = B()
print (b.calculate(1))
2
但是虚拟覆盖是可能的 Python:
import my_lib
class B(my_lib.A):
def override_me(self, a):
return 5*a
b = B()
print (b.calculate(1))
5
我有一个带有虚拟方法的 C++ class:
//C++ class一个 {
public:
A() {};
virtual int override_me(int a) {return 2*a;};
int calculate(int a) { return this->override_me(a) ;}
};
我想做的是用 Boost.python 将此 class 公开给 Python,从 Python 中的此 class 继承并拥有正确覆盖调用:
#python:
class B(A):
def override_me(self, a):
return 5*a
b = B()
b.calculate(1) # should return 5 instead of 2
我想对纯虚函数做同样的事情。我正在寻找一种不在 class A 上用 C++ 创建任何包装器 class 的方法。这可能吗?如果是/如果不是,我该怎么做?
您可以在 class 周围提供一个精简包装器,将 override_me
方法调用委托给 boost::python
特定的覆盖函数。
派生的 class calculate
调用简单地调用父 class calculate
方法,所以当它们从 Python 调用时,它们调用 C++ 定义的calculate
方法,但仍允许从 Python:
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() {}
g++ virtual_override.cpp -fPIC -shared -I/path/to/include/python3 -L/path/to/libpython3 -o my_lib.so -lpython3 -lboost_python3
示例:
这允许 non-pure 情况,例如,当 override_me 未被覆盖时,默认函数被调用:
import my_lib
class B(my_lib.A):
pass
b = B()
print (b.calculate(1))
2
但是虚拟覆盖是可能的 Python:
import my_lib
class B(my_lib.A):
def override_me(self, a):
return 5*a
b = B()
print (b.calculate(1))
5